Программирование на Гедымине

Материал из GedeminWiki
(Различия между версиями)
Перейти к: навигация, поиск
 
Строка 26: Строка 26:
 
Установим курсор на наш лукап и нажмем F11 для вызова инспектора объектов, в котором добавим следующее:
 
Установим курсор на наш лукап и нажмем F11 для вызова инспектора объектов, в котором добавим следующее:
 
DataBase – ibdbGAdmin
 
DataBase – ibdbGAdmin
ListTable – GD_GOOD (Таблица справочника ТМЦ)
+
ListTable – [[GD_GOOD]] (Таблица справочника ТМЦ)
 
ListField – NAME (Чтобы в лукапе отображалось именно наименование ТМЦ)
 
ListField – NAME (Чтобы в лукапе отображалось именно наименование ТМЦ)
 
KeyField – ID (Ключевое поле справочника ТМЦ)
 
KeyField – ID (Ключевое поле справочника ТМЦ)

Версия 19:07, 13 ноября 2006

Маленький практикум программирования на Гедымине.

Надеюсь, все уже знают, что на Гедымине можно написать все, что угодно, и лучшим тому доказательством служит прилагаемый к нему Тетрис, но это с одной стороны, с другой – достаточно сложно изучить приемы программирования для этой системы, даже располагая исходниками и очень подробной документацией. Гораздо легче изучить что-то на примере какой-нибудь задачи, маленьких примеров, и уже основываясь на этих кирпичиках, строить в дальнейшем свой код.

Для примера, поставим следующую задачу. Имеется головное предприятие, есть Клиент, который фактически является подразделением нашей компании, но юридически он оформлен, как стороння компания, и этот Клиент желает видеть остатки товара на складах в реальном времени. Однако, ему не должно быть видно ничего, кроме количества товара, склада, на котором находится товар, и цены, по которой ему будет отпускаться этот товар. Цена рассчитывается, допустим, по следующей формуле – ЦЕНА ПОКУПНАЯ * МИН.НАДБАВКА * СТАВКА НДС. Само собой, покупную цену Клиент видеть не должен. В моей реальной задаче, конечно же, алгоритм расчета отпускной цены был несколько сложнее, но для учебных целей примем пока эту формулу.

Приступим. Первым делом создадим форму: Меню СЕРВИС главного окна > Редактор форм > Создать > Простая форма Вводи имя формы MyRemains, префикс usrf_ добавляется автоматически – нажимаем ОК

P01.JPG

Теперь положим на форму лукап, где будем выбирать наименование ТМЦ Нжимаем F10 для вызова панели с палитрой инструментов

P02.JPG

Нажмем на иконку в форме шестеренки в левом нижнем углу панели инструментов

P03.JPG

В поле Поиск по имени наберем gsIBLookupComboBox и нажмем кнопку добавить Установим курсор на наш лукап и нажмем F11 для вызова инспектора объектов, в котором добавим следующее: DataBase – ibdbGAdmin ListTable – GD_GOOD (Таблица справочника ТМЦ) ListField – NAME (Чтобы в лукапе отображалось именно наименование ТМЦ) KeyField – ID (Ключевое поле справочника ТМЦ)

Ну-с, клиент получил возможность выбирать товар, теперь надо дать ему возможность смотреть остатки по этому товару, и цену, по которой он будет его покупать ;)

Сейчас мы будем добавлять на нашу форму необходимые для этого компоненты, и заполнять их свойства в инспекторе объектов. Надеюсь, вы уже уяснили, что панель инструментов вызывается клавишей F10, а инспектор объектов клавишей F11.

Поехали дальше.

Добавим следующие компоненты для работы с базой данных:

TIBDataSet, TDataSource, TIBTransaction, TgsIBGrid

P04.JPG

Установим у добавленных компонентов следующие свойства:

Usrg_IBTransaction1 DefaultDtabase – ibdbGAdmin Active – True

Usrg_IBDataset1 DataBase – ibdbGAdmin Transaction - usrg_IBTransaction1 SelectSQL – “SELECT NAME, 0 AS QUANTITY, 0 AS DEPARTMENT FROM GD_GOOD” Active - True usrg_DataSource1 DataSet - usrg_IBDataSet1

usrg_gsIBGrid1 DataSource - usrg_DataSource1

На панели инструментов (вызываем по F10) нажимаем сохранить и выйти. Пока наша форма доступна только из редактора форм, далее я покажу, как вызывать ее из исследователя.

В принципе, те, кто знаком с Делфи, вряд ли узнали что-то новое, но я бы советовал при работе с базой использовать эти компоненты, как нативные для Гедемина, ибо, если вы полазили по менюшкам панели инструментов, то заметили, что можно использовать и другие компоненты для работы с базой, унаследованные из Делфи.

Теперь из меню Сервис вызовем Редактор Скрипт-объектов В его проводнике найдем папку Скрипт-функции, раскроем список, правой кнопкой мыши вызовем меню и пункт меню добавить скрипт-функцию. В поле наименование функции введем название gs_ShowMyRemains, и перейдем на закладку Скрипт. Здесь мы увидим что то типа такого

option explicit
function ScriptFunction149168626_604386861
end function

Если теперь нажать красную галочку редактора скрипт-объектов , то умница Гедемин предложит скорректировать название нашей функции, в результате получится вот такой текст

option explicit
function gs_ShowMyRemains
end function 

В теле нашей функции добавим следующий код

  Dim F
  set F = Application.FindComponent("usrf_MYRemains")
  if not Assigned(F) then
    set F = Designer.CreateObject(Application, "usrf_MYRemains", "usrf_MYRemains")
  end if
  if F.Visible then
    F.BringToFront
  else
    F.Show
  end if

Сохраним нашу функцию все той же красной галочкой или Ctrl-S и закроем редактор скрипт-объектов Теперь в исследователе Гедемина правой кнопкой мыши выбираем добавить, в появившемся окне в желтом поле Наименование пишем «Показать остатки», отмечаем в выборе Функция, в поле скрипт-функция указываем наименование нашей функции gs_ShowMyRemains, нажимаем ОК Теперь, если мы найдем в исследователе пункт Показать остатки и кликнем по нему, у нас на экране появится наша форма для просмотра остатков. Теперь ее уже можно редактировать не залезая в меню редактора форм, а просто вызвав его сочетанием клавиш Ctrl+A+E Осталось сделать так, чтобы при выборе какого-нибудь ТМЦ в гриде отображались остатки по этому ТМЦ, этим мы сейчас и займемся.

Остатки будем выбирать SQL запросом, сейчас я приведу код запроса, который выводит все текущие остатки по всем ТМЦ, и постараюсь объяснить, как он работает, позже мы его слегка модифицируем, итак:

SELECT
SUM(M.DEBIT - M.CREDIT) As SALDOEND,
G.NAME,
GR.NAME AS GROUPNAME,
CON.NAME As DEPARTNAME,
C.USR$INV_COSTBUYNCU
FROM INV_MOVEMENT M
JOIN GD_CONTACT CON ON M.contactkey = CON.ID AND CON.contacttype IN (2,4)
JOIN GD_CONTACT CON2 ON CON2.lb <= CON.LB AND CON2.RB >= CON.rb AND CON2.ID = <COMPANYKEY/>
JOIN INV_CARD C ON C.ID = M.CARDKEY
LEFT JOIN GD_GOOD G ON G.ID = c.goodkey
LEFT JOIN GD_GOODGROUP GR ON GR.ID = G.GROUPKEY
GROUP BY
G.NAME,
GR.NAME,
C.USR$INV_COSTBUYNCU,
CON.NAME
HAVING  SUM(M.DEBIT - M.CREDIT) > 0

Как видите, мы будем использовать следующие таблицы GD_GOOD - эта таблица используется для хранения справочника ТМЦ GD_GOODGROUP – товарные группы GD_CONTACT – справочник организаций, физ.лиц, сотрудников и подразделений INV_CARD – таблица для хранения карточек ТМЦ INV_MOVEMENT – таблица, в которой сохраняется информация о движении ТМЦ. Обратите внимание, что на каждое ОДНО движение (приход, расход, перемещение, списание и т.д) в таблице создаются минимум ДВЕ записи(может быть и больше) – одна с указанием от кого товар пришел(кредит), вторая куда(кому) пришел этот же товар(дебет).

Обратите внимание на то, как мы выбираем только те подразделения, сотрудников, которые входят в нашу компанию

JOIN GD_CONTACT CON ON M.contactkey = CON.ID AND CON.contacttype IN (2,4)
JOIN GD_CONTACT CON2 ON CON2.lb <= CON.LB AND CON2.RB >= CON.rb AND CON2.ID = <COMPANYKEY/>

Здесь идет связка по LB, RB – более подробно об этом можно почитать в статье Sysdba об интервальных деревьях, и в документации разработчика. Здесь же только отметим, что подобная технология нашла широкое применение в справочниках Гедемина. <COMPANYKEY/> - это SQL-константа, равная ID рабочей компании. Кстати говоря, нужно иметь в виду, что подобный запрос с использованием SQL-констант будет хорошо работать в SQL-редакторе Гедемина и в скриптах Гедемина, но уже в IB-Expert вместо них придется подставлять реальные идентификаторы, ибо тот же IB-Expert о них не имеет никакого понятия ;) Существуют и другие SQL-константы, их описание и назначение приведены в руководстве разработчика.

Ну а теперь, собственно, сделаем код, который при выборе ТМЦ покажет текущие остатки Из исследователя запустим Показать остатки. Кликнем мышкой по нашей форме, чтобы она попала в фокус и нажмем Ctrl+A+E Кликнем на лукапе выбора ТМЦ, нажмем F11 для вызова инспектора свойств этого компонента, зайдем на закладку события, выберем OnChange, отредактируем это событие. Вы, наверное уже догадались, что это событие возникает, когда мы выбираем в нашем лукапе какой-нибудь ТМЦ. Напишем следующий код:

   Dim Creator, usrg_gsIBLookupComboBox1, usrg_IBDataSet1
    Set Creator = New TCreator
    set usrg_gsIBLookupComboBox1 =   Sender.OwnerForm.GetComponent("usrg_gsIBLookupComboBox1")
    set usrg_IBDataSet1 = Sender.OwnerForm.GetComponent("usrg_IBDataSet1")
    if  Assigned(usrg_IBDataSet1.Transaction) then usrg_IBDataSet1.Transaction.Commit
    usrg_IBDataSet1.Close
    usrg_IBDataSet1.SelectSQL.Text = "SELECT " & _
      "SUM(M.DEBIT - M.CREDIT) As SALDOEND, " & _
      "G.NAME, " & _
      "GR.NAME AS GROUPNAME, " & _
      "CON.NAME As DEPARTNAME, " & _
      "C.USR$INV_COSTBUYNCU " & _
      "FROM INV_MOVEMENT M " & _
      "JOIN GD_CONTACT CON ON M.contactkey = CON.ID AND CON.contacttype IN (2,4) " & _
      "JOIN GD_CONTACT CON2 ON CON2.lb <= CON.LB AND CON2.RB >= CON.rb AND CON2.ID = <COMPANYKEY/> " & _
      "JOIN INV_CARD C ON C.ID = M.CARDKEY " & _
      "LEFT JOIN GD_GOOD G ON G.ID = c.goodkey " & _
      "LEFT JOIN GD_GOODGROUP GR ON GR.ID = G.GROUPKEY " & _
      "WHERE G.ID = :GOODKEY " & _
      "GROUP BY " & _
      "G.NAME, " & _
      "GR.NAME, " & _
      "C.USR$INV_COSTBUYNCU, " & _
      "CON.NAME " & _
      "HAVING  SUM(M.DEBIT - M.CREDIT) > 0 "


    usrg_IBDataSet1.ParamByName("GOODKEY").AsInteger = usrg_gsIBLookupComboBox1.CurrentKeyInt
    usrg_IBDataSet1.Active = True  

Обратим внимание на небольшую модификацию кода SQL-запроса:

 "WHERE G.ID = :GOODKEY "

Таким образом мы ограничиваем выборку остатков по конкретному ТМЦ, а значение параметра :GOODKEY получаем из свойства лукапа CurrentKeyInt, которое будет равно идентификатору ТМЦ в таблице GD_GOOD. Сохраняемся, выходим, запускаем из исследователя Показать остатки, в лукапе выбираем ТМЦ по вкусу, наслаждаемся результатом ;)

Ну а завтра мы научимся сохранять настройки грида и самой формы в хранилище, облагородим внешний вид нашего замечательного окошка

To be Continued...

--KLN 07:58, 6 июня 2006 (EDT)

Персональные инструменты
Пространства имён

Варианты
Действия
Навигация
Инструменты