Модераторы: Rodman
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Формирование DBTreeView на лету из даты, Может есть лучший способ? 
:(
    Опции темы
Rodeon
Дата 16.12.2016, 18:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 112
Регистрация: 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
PM MAIL   Вверх
Google
  Дата 21.11.2017, 02:10 (ссылка)  





  Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Базы данных и репортинг"
Vit
Петрович

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами


Обязательно указание:

1. Базы данных (Paradox, Oracle и т.п.)

2. Способа доступа (ADO, BDE и т.д.)


  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • Вопросы по SQL и вопросы по базам данных не связанные с Дельфи задавать здесь

FAQ раздела лежит здесь!


Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Vit, Петрович.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Базы данных и репортинг | Следующая тема »


 




[ Время генерации скрипта: 0.1331 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.