Шустрый
Профиль
Группа: Участник
Сообщений: 124
Регистрация: 28.8.2008
Где: Россия, Ухта
Репутация: нет Всего: нет
|
Задача: добавление приказа в базу данных, и в DBTreeView. Чтобы автоматически строило дерево ГОД - Месяц - Номер приказа. Автоматом создавало недостающие ноды. Имеем: база данных FireByrd. Создана база данных, добавил поле ID_PRIKAZ по которому связь с другой базой: Код | CREATE TABLE PRIKAZ_TREE ( ID INTEGER NOT NULL, ID_ID INTEGER NOT NULL, "DISPLAY" CHAR(20) NOT NULL, ID_SORT SMALLINT NOT NULL, ID_PRIKAZ INTEGER NOT NULL );
ALTER TABLE PRIKAZ_TREE ADD CONSTRAINT PK_PRIKAZ_TREE PRIMARY KEY (ID);
|
Создан генератор: Код | CREATE SEQUENCE GEN_PRIKAZ_TREE_ID;
|
Создан триггер-автоинкремент: Код | CREATE OR ALTER TRIGGER PRIKAZ_TREE_BI FOR PRIKAZ_TREE ACTIVE BEFORE INSERT POSITION 0 as begin if (new.id is null) then new.id = gen_id(GEN_PRIKAZ_TREE_ID,1); end
|
Добавленны константы: Код | Const Month: array[1..12] of String = ('Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь');
|
Добавленны переменные: Код | Var ID_return, Prymary_Node, Secondary_Node: Integer;
|
Собственно сама часть программы, все работает, не жалуюсь, создает дерево как с пустого места, так и если был уже год, месяц или и то и другое: Код | begin Prymary_Node:=-1; Secondary_Node:=-1; MainForm.IBQuery1.Active:=False; MainForm.IBQuery1.SQL.Text:='select * from PRIKAZ_TREE WHERE (DISPLAY=:0)'; MainForm.IBQuery1.Params[0].AsString:=IntToStr(YearOf(sDateEdit1.Date)); MainForm.IBQuery1.Active:=True; {Если нод с таким именем есть, в нашем случае год, то получаем его ID, если нету то создаем} If MainForm.IBQuery1.RecordCount>0 then Prymary_Node:=MainForm.IBQuery1.FieldValues['ID'] else Begin Prymary_Node:=0; with MainForm.IBQuery1 do Begin SQL.Text:=('INSERT INTO PRIKAZ_TREE (ID_ID, DISPLAY, ID_SORT) VALUES (:ID_ID, :DISPLAY, :ID_SORT)'); ParamByname('ID_ID').AsInteger := Prymary_Node; ParamByname('DISPLAY').AsString :=IntToStr(YearOf(sDateEdit1.Date)); ParamByname('ID_SORT').AsInteger :=YearOf(sDateEdit1.Date); ExecSQL; {Получаем ID вновь созданного нода - год} SQL.Text:=('select gen_id(GEN_PRIKAZ_TREE_ID,0) from rdb$database'); Open; ID_return:=FieldByName('GEN_ID').AsInteger; Close; {Сразу создаем месяц, так как его не могло быть если нет года} SQL.Text:=('INSERT INTO PRIKAZ_TREE (ID_ID, DISPLAY, ID_SORT) VALUES (:ID_ID, :DISPLAY, :ID_SORT)'); ParamByname('ID_ID').AsInteger := ID_return; ParamByname('DISPLAY').AsString :=Month[MonthOf(sDateEdit1.Date)]; ParamByname('ID_SORT').AsInteger :=MonthOf(sDateEdit1.Date); ExecSQL; {Снова получаем ID вновь созданного нода - месяц} SQL.Text:=('select gen_id(GEN_PRIKAZ_TREE_ID,0) from rdb$database'); Open; ID_return:=FieldByName('GEN_ID').AsInteger; Close; {Добавляем наконец номер приказа в созданный год, месяц} SQL.Text:=('INSERT INTO PRIKAZ_TREE (ID_ID, DISPLAY, ID_SORT) VALUES (:ID_ID, :DISPLAY, :ID_SORT)'); ParamByname('ID_ID').AsInteger := ID_return; ParamByname('DISPLAY').AsString :=sEdit1.Text; If TryStrToInt(sEdit1.Text, i) then ParamByname('ID_SORT').AsInteger:=StrToInt(sEdit1.Text) Else ParamByname('ID_SORT').AsInteger:=0; ExecSQL; End; End; {Проверка, если нод с годом уже есть} If Prymary_Node>0 Then with MainForm.IBQuery1 do Begin Active:=False; SQL.Text:='select * from PRIKAZ_TREE WHERE (DISPLAY=:0) AND (ID_ID=:1)'; Params[0].AsString:=Month[MonthOf(sDateEdit1.Date)]; Params[1].AsInteger:=Prymary_Node; Active:=True; If RecordCount>0 then Begin Prymary_Node:=MainForm.IBQuery1.FieldValues['ID']; {Если есть месяц, год добавляем номер приказа} SQL.Text:=('INSERT INTO PRIKAZ_TREE (ID_ID, DISPLAY, ID_SORT) VALUES (:ID_ID, :DISPLAY, :ID_SORT)'); ParamByname('ID_ID').AsInteger := Prymary_Node; ParamByname('DISPLAY').AsString :=sEdit1.Text; If TryStrToInt(sEdit1.Text, i) then ParamByname('ID_SORT').AsInteger:=StrToInt(sEdit1.Text) Else ParamByname('ID_SORT').AsInteger:=0; ExecSQL; End else Begin {Если нет месяца - создаем месяц} SQL.Text:=('INSERT INTO PRIKAZ_TREE (ID_ID, DISPLAY, ID_SORT) VALUES (:ID_ID, :DISPLAY, :ID_SORT)'); ParamByname('ID_ID').AsInteger := Prymary_Node; ParamByname('DISPLAY').AsString :=Month[MonthOf(sDateEdit1.Date)]; ParamByname('ID_SORT').AsInteger :=MonthOf(sDateEdit1.Date); ExecSQL; {Получаем ID вновь созданного нода - месяц} SQL.Text:=('select gen_id(GEN_PRIKAZ_TREE_ID,0) from rdb$database'); Open; ID_return:=FieldByName('GEN_ID').AsInteger; Close; {Добавляем наконец номер приказа в созданный месяц} SQL.Text:=('INSERT INTO PRIKAZ_TREE (ID_ID, DISPLAY, ID_SORT) VALUES (:ID_ID, :DISPLAY, :ID_SORT)'); ParamByname('ID_ID').AsInteger := ID_return; ParamByname('DISPLAY').AsString :=sEdit1.Text; If TryStrToInt(sEdit1.Text, i) then ParamByname('ID_SORT').AsInteger:=StrToInt(sEdit1.Text) Else ParamByname('ID_SORT').AsInteger:=0; ExecSQL; End; End;
|
Сортировку решил добавлением еще одного поля ID_SORT. Собственно в который заносится Integer года, месяц и если возможно №приказа, если невозможно преобразовать №приказа в число, то 0. Запрос стал: Код | select * from PRIKAZ_TREE ORDER BY ID_SORT
|
Вопрос в следующем: может как-то можно все это упростить? Это сообщение отредактировал(а) Rodeon - 17.12.2016, 09:25
|