Теперь книг много разных. Но и в хороших книгах, которые встречаются не часто, по прежнему не просто найти ответ на вопрос "когда же достаточно электронной таблицы типа Excel, а в каком случае удобно использовать базу данных?"
И вывел я для себя вот такую формулу много лет назад:
все, из чего можно составить список и пронумеровать - есть содержимое для отдельной таблицы базы данных.
Если вернуться на пару десятков уроков назад, то в структуре созданной нами для реализации функционала программы "Расходы" присутствует ряд таких таблиц:
- Перечень валют
- Перечень счетов
- Перечень мемориальных ордеров
На них же ссылаются пункты меню:
Сразу хотелось бы предупредить, что вряд ли я сообщу что-то новое в дополнение к тому, что уже было сказано в предыдущих уроках.
Итак, напомню общий алгоритм:
1. Добавить форму в проект
2. Прописать ссылку на модуль формы в Uses вызывающей формы
3. Исключить из автоматически запускаемых
4. Добавить процедуру (или несколько) для вызова новой формы
1. Форма для работы со списком счетов будет выглядеть так:
Последняя колонка должна быть недоступной для редактирования, так как значение для нее будет задаваться как значение по умолчанию, а для его изменения мы позже создадим инструмент (форму).
2. Укажите ссылку в разделе:
implementation
Uses Main;
С учетом этого, источником данных для этой формы может вполне служить источник данных, расположенный на главной форме. Установите в свойствах: DataSource=MainFrm.DataSourceAcc.
3. Напомню: Меню-Project-Options:
4. В описание класса главной формы:
type
TMainFrm = class(TForm)
...
в секцию нужно добавить описание новой подпрограммы:
private
{ Private declarations }
procedure ShowAccounts();
А затем в секции реализации (implementation)
дополнить ссылки на другие модули еще одной
implementation
Uses
MOs
, Oborot
, Accounts
;
ну, и написать, собственно, код этой процедуры:
procedure TMainFrm.ShowAccounts();
Begin
Application.CreateForm(TAccountsFrm, AccountsFrm);
AccountsFrm.ShowMoDal;
AccountsFrm.Free;
StatusBarUpdate;
end;
Эти операторы я не случайно выделил в отдельную процедуру. Просто эта форма будет вызываться в разных местах программы, чтобы не повторялся код.
И последнее - создать Action или напрямую - обработчик выбора пункта меню "Кодификаторы - Счета"
procedure TMainFrm.N1Click(Sender: TObject);
begin
MySelect.MySel_IDAcc:=0;
MySelect.MySel_AccName:='';
ShowAccounts;
end;
Теперь стоит задуматься: базу данных мы спроектировали надежную (это я про то, что после компиляции программы "Расходы" мне удалось добавить новую запись в список (кодификатор) счетов, и ничего не рухнуло): при добавлении новой записи подставились какие-то значения по-умолчанию.
Но, может быть, удобнее задать иные? Переделать базу данных можно, пока она у Вас одна, задачка локальная и Вы - сам себе командир. Но, если Вы работаете над большим и сложным проектом, то это не всегда бывает возможно. Бывает даже так: кто-то разрабатывает интерфейсы, а совсем другие люди разрабатывают или уже разработали базы данных.
Поэтому, я предлагаю написать еще одну процедуру, которая будет подставлять нужные нам значения по умолчанию в только что добавленную новую запись (для события AfterInsert компонента ADOTableAcc, расположенного на главной форме):
procedure TMainFrm.ADOTableAccAfterInsert(DataSet: TDataSet);
begin
ADOTableAcc.FieldByName('Val').Value:=MySelect.MySel_IDVal;
ADOTableAcc.FieldByName('Ost_D').Value:=0;
ADOTableAcc.FieldByName('Ost_K').Value:=0;
ADOTableAcc.FieldByName('Analiz').Value:=True;
ADOTableAcc.FieldByName('Groups').Value:=False;
end;
Обращаю Ваше внимание, что последний оператор задает значение, отличное от значения по умолчанию, установленное в конструкторе таблицы базы данных:
Еще один момент:
для того же компонента ADOTableAcc нужен обработчик события BeforeEdit (в момент начала редактирования необходимо запомнить ID строки, соответствующей редактируемому счету)
procedure TMainFrm.ADOTableAccBeforeEdit(DataSet: TDataSet);
begin
p_ID:= ADOTableAcc.FieldByName('ID').value;
end;
И последнее:
без проверки введенных значений возможна ситуация задваивания значений:
Поэтому, прежде, чем сохранить новое или отредактированное значение счета, нужно учинить ему очень строгую проверку по событию BeforePost:
procedure TMainFrm.ADOTableAccBeforePost(DataSet: TDataSet);
Var MyStr: String;
begin
MyStr:= ADOTableAcc.FieldByName('Name').Text;
if (MyStr='')
then
begin
MyMessenger.TitleString:='Ошибка';
MyMessenger.MessageString:='Пустые значения не допустимы';
MyMessenger.Buttons:=[mbOK];
MyMessenger.ShowMessage;
abort;
exit;
end;
TempQuery.Active:=False;
TempQuery.Connection:=ADOConnection1;
TempQuery.SQL.Clear;
TempQuery.SQL.Add('SELECT * FROM Accounts WHERE (Name='''+MyStr+''') AND (ID<>'+IntToStr(p_ID)+')');
TempQuery.Active:=True;
If not TempQuery.Eof
Then
begin
MyMessenger.TitleString:='Ошибка';
MyMessenger.MessageString:='Счет '''+MyStr+''' уже есть.';
MyMessenger.Buttons:=[mbOK];
MyMessenger.ShowMessage;
ADOTableAcc.FieldByName('Name').Text:='';
Abort;
end;
TempQuery.Active:=False;
end;
В результате срабатывания этой процедуры возможны предупреждения о повторяющемся или пустом значении:
Аналогичные (но, спешу успокоить: чуть более простые) нужно проделать для других кодификаторов (Мемориальные ордера и Валюты).
procedure TMainFrm.N2Click(Sender: TObject);
begin
// Обработка пункта меню Кодификаторы-Мемориальные ордера
ShowMOs;
end;
- кодификатор мемориальных ордеров у нас уже имеется, остается только выполнить обработку пункта меню.
Для кодификатора валют понадобится добавить на главную форму пару компонентов (таблицу и источник данных: TADOTable и TDataSource), назначить их свойства, как уже это делали не однократно, не забыть добавить активацию этой таблицы в соответствующей процедуре и написать вызов формы:
procedure TMainFrm.N_ValClick(Sender: TObject);
begin
// Вызов справочника валют
Application.CreateForm(TValFrm, ValFrm);
ValFrm.ShowModal;
ValFrm.Free;
StatusBarUpdate;
// Фильтр по счетам одной валюты
ADOTableAcc.Filter:='Val='+IntToStr(MySelect.MySel_IDVal);
ADOTableAcc.Filtered:=True;
end;
Еще про один справочник - "Группы затрат" я предполагаю поговорить в одном из ближайших уроков.
Комментариев нет:
Отправить комментарий
Примечание. Отправлять комментарии могут только участники этого блога.