Skip to forum content
My Visual Database
A Simple Solution for Creating Databases
You are not logged in. Please login or register.
Active topics Unanswered topics
Search options (Page 58 of 60)
Topics by k245 User defined search
Posts found: 1,426 to 1,450 of 1,480
netros wrote:Речь идёт именно о таблице табель: мне не хочется создавать 31 поле, по количеству дней.
Кроме ID, в табеле всего два поля:
А вот заполнять данные в табличку на экране для привычного визуального представления (календарь или табельный лист) придётся скриптом, а для печатной формы сделать временную таблицу.
netros wrote:для табелирования народа.
Т.е. просто проставить в какую смену кто когда вышел
А вытащить - просто пройтись циклом по строке
Рекомендую создать 2 таблицы: работники и табель выхода на работу. Всякие "оптимизации" с запихиванием данных в одно поле на пользу не пойдут, а все вычисления лучше делать не скриптами, а SQL-запросами.
Экспертные системы подобного типа делаются на основе бинарного дерева: пользователю по очереди задаются вопросы, отвечая на которые "да" или "нет" программа перемещается по дереву вариантов. Когда достигнут конечный узел, программа сообщает свое решение. Пользователь либо соглашается, либо отрицает решение системы. В этом случае система предлагает ввести дополнительный вопрос, чтобы добавить ещё одно ветвление в дереве и новый ответ (или два новых ответа).
Для реализации подобной системы понадобится следующая структура дерева вопросов
ID - идентификатор (создаётся автоматически)
Node_text - текст вопроса или текст ответа
ID_positive - идентификатор узла для перехода при положительном ответе
ID_negative - идентификатор узла для перехода при отрицательном ответе
Сам алгоритм реализуется скриптом, из элементов интерфейса понадобится Label (для отображение текущего вопроса или ответа) и две кнопки (Да/Нет).
netros wrote:проще говоря месячный календарь в одно поле, или для каждого числа всё-таки придётся создавать своё поле?
Запихать можно, но будет ли удобно вытаскивать?
Уточните вашу бизнес-задачу. Для чего нужен календарь?
Схема структуры предприятия понятна, но непонятно, зачем её реализовывать Чтобы определить, кто кому подчиняется и у кого сколько подчиненных? Тогда - да, это нужно.
Что мы имеет на схеме? Иерархический список должностей, в котором некоторые должности представлены группами (названием отдела), которые не должны выбираться в качестве должности сотрудника а служат только для организации иерархической структуры. На практике это дерево расширяется на уровне отделов конкретными должностями: монтажник, штукатур, менеджер, бухгалтер и т.д. Тогда получаем структуру:
ID - идентификатор (поле создаётся автоматом)
Parent_ID - родительский элемент
Name - название должности или отдела
isGroup - признак отдела
При добавлении сотрудника ему присваивается должность, отдел назначать нельзя, но его можно определить запросом.
Илья Б. wrote:...как защитить script.dcu от просмотра пользователем?
Защитить файл script.dcu от чтения нельзя, но можно замаскировать текст логина/пароля (или другие конфиденциальные данные). Напишите простую функцию преобразования строки (перестановки и/или замены символов), чтобы в исходнике не хранились данные для подключения в явном виде.
Попробуйте сделать так:
Разместить PageControl в верхней части формы, уменьшив его размер так, чтобы отображались только закладки.
Ниже разместить TableGrid
Добавить скрипт генерации закладок
Добавить скрипт фильтрации при нажатии на закладку
Вот пример:
procedure CreateTabMenu;
var
Menu: TDataSet;
TabSheet: TTabSheet;
s: string;
begin
// типы отчётов
frmMain.pgcFinStatType.Pages[0].Free;
s := 'select * from fin_stat_type order by id;';
SQLQuery(s,Menu);
while not Menu.Eof do
begin
TabSheet := TTabSheet.Create(frmMain);
TabSheet.Caption := Menu.FieldByName('name').asString;
TabSheet.PageControl := frmMain.pgcFinStatType;
Menu.next;
end;
frmMain_pgcFinStatType_OnChange (frmMain.pgcFinStatType);
end;
Фильтрация данных настроена как функция "[ПОИСК]" в кнопке frmMain.btnFinStatUpd
procedure frmMain_pgcFinStatType_OnChange (Sender: TObject);
begin
// установить фильтр по типу статистики
frmMain.cmbFinStatType.dbItemID := frmMain.pgcFinStatType.ActivePageIndex+1;
frmMain.btnFinStatUpd.Click;
end;
Пример сделан с допущением, что ID в таблице fin_stat_type идут последовательно: 1,2,3.. Если это условие не соблюдается (например, если записи удаляются), то можно записывать ID записи в свойство TabSheet.tag, а затем передавать его в фильтр.
wertyby wrote:Дмитрий никак не могу понять как активировать вертикальный скролл на форме по вертикали. По горизонтали включается но он не нужен. а вертикальный никак?
Предполагаю, что речь идет не о скроле формы, а о скроле записей таблицы при наведении мыши и кручении колесика. Для себя решил это тем, что в событии OnMouseEnter для таблицы передаю ей фокус:
procedure Form1_TableGrid1_OnMouseEnter (Sender: TObject);
begin
Form1.TableGrid1.SetFocus;
end;
Как выяснилось, это не совсем удобно, особенно если на этой же форме есть поля ввода данных (например, фильтр).
Хотелось бы услышать лучшее решение.
max1779signal wrote:...но мне надо узнать этот id еще до сохранения.
Предполагаю, что реализованный в MVDB механизм формирования ID записей обеспечивает целостность данных и нормальную работу СУБД, а Ваша прикладная задача, возможно, имеет другое, более безопасное решение.
Если не секрет, для чего может понадобиться ID недобавленной в базу записи?
netros wrote: UpdateDatabase('таблица');
В каких случаях необходимо использовать эту команду?
Bullet3203 wrote:...При нажатии кнопки отправить, у получателя было уведомление что ему пришло сообщение и запрос на передачу файлов. Сам файл автоматом сохранялся в базе, но после получение его пользователем он бы с базы удалялся. Возможно ли такое?)
Можно по таймеру (например, раз в минуту или чаще) проверять, не появилась ли новая запись в базе. А после выгрузки (сохранения) файла - удалять запись.
Скорее всего, вопрос имеет отношение к системе защиты программы. На форуме есть куча примеров, которые используют метки времени для ограничения функциональности демо-версий, но всё это легко обходится переустановкой времени на локальной машине. Если же время/дату запрашивать по сети, то надёжность этого элемента защиты будет выше.
mcsimm wrote:Может через систему это как-то делать, например, через службу времени Windows :
w32tm /stripchart /computer:time.windows.com /samples:1 /dataonly > temp.txt,
Кстати, неплохой вариант
Непонятно только, как запустить выполнение этой строки из приложения MyVisualDatabase...
Bullet3203 wrote:Здравствуйте! Возможно ли реализовать передачу файлов конкретному пользователю? (работа в локальной сети)
Несколько экстравагантное решение, но для небольших файлов вполне применимое: записывайте файлы в базу данных; с помощью системы прав доступа настройте ограничения доступа к записям для обеспечения приватности.
В общем случае нужно добавить обработчик на событие PageControl.onChange . Дальнейшие действия зависят от структуры данных. Если ваша база нормализованная, то типы продукции - это справочник, а в таблице с продукцией хранится ссылка на него. Тогда обработчик может быть таким:
procedure frmMain_pgcFinStatType_OnChange (Sender: TObject);
begin
// установить фильтр по типу
frmMain.cmbFinStatType.dbItemID := frmMain.pgcFinStatType.ActivePageIndex+1;
// обновить таблицу
frmMain.btnFinStatUpd.Click;
end;
В этом примере устанавливаем ID равным номеру страницы + 1, то есть не по названию, а по ID. А затем нажимаем кнопку, в которой реализован метод фильтрации данных.
MessageDlg выдаёт ошибку:
begin
if MessageDlg('Произвести загрузку из текстовых файлов?',mtWarning,[mbOK,mbCancel],0)=mrOK then
begin
ShowMessage('!');
end;
ShowMessage('!!!');
end.
Сохранение имён визуальных компонент при копировании их через буфер обмена. Сейчас при вставке имена компонентов теряются (устанавливаются по умолчанию), а так как скрипты привязываются к конкретным названиям, то при переносе формы в другой проект много времени теряется на переименование компонентов.
DriveSoft wrote:В вашем случае необходимо подключиться к MySQL с помощью скрипта, таким образом вы сможете сделать свой диалог подключения к БД, а также выполнить необходимые SQL запросы, чтобы проверить наличие БД на сервере и при необходимости создать ее...
Я подключаюсь к БД с помощью скрипта. Однако, не хотелось бы дублировать информацию о структуре базы в скриптах - это действительно неудобно, так как при изменении структуры нужно будет каждый раз править эти самые скрипты.
Либо мне придётся "изобретать велосипед" - свой скрипт, который из tables.ini будет создавать аналогичную структуру в базе MySQL. Но мне хочется использовать проверенное, рабочее решение.
DriveSoft wrote:SQLExecute('CREATE DATABASE IF NOT EXISTS `DBName`;');
Этот скрипт создаёт базу в случае её отсутствия. Но мне нужно только определить её наличие или отсутствие. Ушёл читать описание команд SQL для управления БД...
DriveSoft wrote:...могу попробовать добавить функцию в скрипт, которая бы создавала структуру без необходимости использовать SQL.
Да, это было бы самым простым (для разработчика прикладной системы) решением
P.S.
Уважаемые разработчики приложений платформы MyVisualDatabase!
А как вы создаёте дистрибутивы приложений для MySQL?
Как с помощью скрипта:
1) определить, что нужная база отсутствует на сервере
2) создать нужную базу
3) создать структуру таблиц, нужных для работы приложения
4) загрузить в таблицы данные (этот пункт, в принципе, понятен, внесён для полноты картины)
Или как отобразить это окошко, в котором реализованы пункты 1-3 и которое есть в среде разработки:
Всё это очень нужно для настройки приложения у конечного пользователя, который не купил среду разработки и исходники программы.
Конечная цель - создание дистрибутива пользовательского приложения. Хотелось бы обойтись только средствами MyVisualDatabase и пока бесплатной Inno Setup, как описано здесь: http://myvisualdatabase.com/forum/viewt … 249#p19249
http://myvisualdatabase.com/forum/viewt … 754#p22754
mcsimm wrote:Накидал в редакторе и Пейнте примерный вид такой настройки
Пожалуй, добавлю настроек
...действительно, файл не загружается
Мне видится это так: после создания стандартного sqlite.db средствами MyVisual Database его можно переименовать в MyFile.db средствами операционной системы. А затем использовать по мере необходимости.
Подключение:
SQLExecute('ATTACH DATABASE ''d:\testDB.db'' as ''TEST''');
Использование
SELECT TEST.person.firstname, TEST.person.lastname FROM TEST.person
но при этом ваш проект должен использовать SQLite в качестве основной СУБД
Подсмотрено здесь: http://myvisualdatabase.com/forum/viewtopic.php?id=1804
jonibek wrote:Для чего нужна рекурсия и что даст данный код, объясните чайнику.
Рекурсия - это приём в программировании, когда функция или процедура вызывает саму себя.
function load(var A:integer):integer;
var
i: integer;
begin
i := A;
if A<5 then
result := load(A+1) + i
else
result := A;
end;
У меня была гипотеза, что FastScript некорректно работает с рекурсивными функциями или процедурами. Данный код опроверг эту гипотезу, и уважаемый iacovlogica так же подтвердил, что с рекурсией всё в порядке. Никакой другой пользы от данного кода нет
А вот использование в рекурсивной процедуре функции SQLQuery() приводит к фатальной ошибке, о чем, собственно и весь этот топик
Конечно, возможно Например, так:
iacovlogica wrote:...Глобально объявить массив датасет...
Интересный вариант, но, скорей всего результат будет таким же
Прошлым вечером я поставил кучу экспериментов и в результате выяснил, что любое сочетание SQLQuery() и рекурсивного вызова функций или процедур фатально. Не знаю конкретно, в чём там дело, скорей всего в особенностях работы FastScript.
Если гора не идёт к Магомету, то... меняем структуру данных:
Теперь можно обойтись без рекурсии, пожертвовав удобностью настройки меню. Структура меню определяется строковым полем LEVEL (Уровень). Обычно это поле заполняется на триггерах БД на основе id_parent и order_num, но можно и ручками внести
Код получился сравнительно простой, загружает до 10 уровней вложенности (на практике больше трёх уровней вложенности в меню не встречал)
// загрузка за один присест
procedure LoadMenu;
var
Results: TDataSet;
// до 10 уровней вложенности меню!
ParentList: array[0..9] of TMenuItem;
miChild: TMenuItem;
sForm: string;
iCurLevel: integer;
index: integer;
s: string;
begin
S :='SELECT main_menu.name, main_menu.form, main_menu.level FROM main_menu '+
'left join menu_roles on menu_roles.id_main_menu = main_menu.id '+
'WHERE (menu_roles.id_roles='+inttostr(RoleID)+') order by level';
SQLQuery(S,Results);
while not Results.Eof do
begin
sForm := Results.FieldByName('form').AsString;
iCurLevel := length(Results.FieldByName('level').AsString)-1;
miChild := TMenuItem.Create (MainMenu);
if iCurLevel = 0 then
begin
MainMenu.Items.Add(miChild);
end
else
begin
TMenuItem(ParentList[iCurLevel-1]).Add(miChild)
end;
ParentList[iCurLevel] := miChild;
//
miChild.Caption := Results.FieldByName('name').AsString;
// к пункту меню привязана либо форма, либо вложенные пункты меню
if sForm<>'' then
begin
miChild.OnClick := @MenuItemClick;
index := FormList.IndexOf(sForm);
if index>=0 then
miChild.Tag := index
else
begin
ShowMessage('Wrong form name: '+sForm)
end
end;
Results.Next;
end;
end;
Результат радует:
Posts found: 1,426 to 1,450 of 1,480