Главная
КОМПАС-CLOUD
Скачать
Цены   
Вебинары
Новости
Контакты
Решение для

  Мастер бизнес-процедур

Вопрос:
Не удаляется бизнес-процедура. Могу удалить только вновь созданную процедуру. Из поставки не удаляется.

Ответ:
Начиная с версии 12.86, пользователь имеющий право создавать настройки на своем уровне (в данном случае - 30), не может ничего удалять из уровней с более низким приоритетом. Для удаления описания с более низким приоритетом нужен priority.dat с соответствующим приоритетом.
Вопрос:
Из полученных с помощью бизнес-процедуры данных необходимо сформировать отчет. Можно ли использовать готовый шаблон, и, если да,то как его заполнить? Причем в шаблоне для формирования заголовков колонок используется тип "шахматка".

Ответ:
В настоящее время шахматку из бизнес-процедуры с помощью класса "Отчет" ("Report") сформировать нельзя. Но можно сделать по-другому, используя функцию PrintReport с указанием псевдонима предварительно сформированного в Мастере отчетов шаблона, в котором описана шахматка. Если данные получаются сложными расчетами, произведенными в бизнес-процедуре, то перед печатью отчета их надо записать во временную таблицу, а в шаблоне отчета использовать запросы по этой таблице. Если данные собираются одним запросом, шаблон отчета можно просто построить на основании такого же запроса.

ОБРАТИТЕ ВНИМАНИЕ: если таблица, используемая для записи данных, действительно временная (создана с помощью функции ServerTempTable), ее имя надо передавать в отчет с помощью макропараметра и использовать этот макропараметр в тексте запроса. В бизнес-процедуре реальное имя временной таблицы можно получить с помощью свойства TableName.

Пример бизнес-процедуры:

tbl = ServerTempTable("MY_TABLE")
... (здесь таблица заполняется)
Params = ListBox
... (здесь заполняются значения параметров отчета, если они есть)
Macros = ListBox
Macros.Add(tbl.TableName)
PrintReport "MY_REPORT","",Params,1,Macros


Пример запроса для данного отчета:

SELECT * FROM %s
ORDER BY DATA_N
Вопрос:
Допустим, предприятие ведет разработку с помощью "Мастеров" где-нибудь отдельно в тестовом режиме. А потом нужно перенести разработку в действующую систему. В целом это можно сделать, поменяв dat-файлы. А вот как быть с хранимыми процедурами?

Ответ:
Хранимые процедуры переносятся из одной БД (или схемы данных) в другую средствами того или иного сервера. Для MS SQL это средство - Data Transformation Wizard, для Oracle - скриптование соответствующих объектов в Enterprise Manager (еще лучше взять такое средство разработки под Oracle, как TOAD), а затем выполнение полученных скриптов на новой схеме.
Вопрос:
В описании таблицы KADRY имеется поле EMAIL, доступ к которому необходимо осуществить из бизнес-процедуры, которая вызывается в качестве обработчика кнопки в ТФ Кадровая картотека. Программа выдает сообщение: "Ошибка в параметрах функции".

Ответ:
Проблема заключается в том, что EMail является методом класса Набор данных. В этом случае, действительно, нет возможности получить значение одноименного поля, так как из контекста не ясно, имеется ли в виду метод класса или его свойство. Пока же предлагаем следующий выход из создавшегося положения:
Q = SQL "SELECT EMAIL AS MAIL FROM KADRY WHERE TAB_N ='"+TAB_N+"'"
print Q.MAIL
Вопрос:
Как корректно из бизнес-процедуры прекратить удаление строки из Табличной формы?

Ответ:
Для того, чтобы из события Перед удалением записи прервать процесс удаления, процедура должна вернуть любое ненулевое значение, например, с помощью следующего оператора:
RETURN 1
Аналогичным образом можно прервать добавление или сохраение записей при обработке соответтсвующих событий.
Вопрос:
Правильно ли написана процедура (СУБД Oracle) для запрета на изменение оклада в штатном расписании, если по этой единице были назначения?
r=SQL"select s.param12 from shtras_m s where
s.sht_ed='"+sht_ed+"' and s.confstate=0 and
s.np_sht_ed=
(select max(np_sht_ed) from
shtras_m where sht_ed=s.sht_ed
and strconf_d<=s.strconf_d
and confstate=0)"
if r.param12<>param12 then
r=SQL"select 1 from nazn where sht_ed='"+sht_ed+"'"
if (r.count<>0) then
a= "По штатной единице имеются назначения"
b=char(10)+"Корректировка запрещена."
print a+b
Return "нет"
end if
end if


Ответ:
Нет. Во-первых, эта процедура не учитывает срок действия назначений. Юридически нельзя изменять оклад только по действующим назначениям. Во-вторых, а почему запрет только на оклад? А на количесвво единиц? А на надбавки?.. В третьих, изменения в штатное расписание можно вносить только документом, в связи с чем можно предложить поставить "защелку" на событие сохранения старой и новой записей:
MessageBox "Действие запрещено."," Любые изменения в штатном расписании производятся документом"
return 1
Вопрос:
Существует ли способ передачи числа (например, 102.00) в файл без потери разделителя целой и дробной части и нулевой части после разделителя. Например, oFile.Write(SUM_D). В файл записывается только 102, а нужно 102.00. Функция STR с параметрами в бизнес-процедуру принимается за ошибку.

Ответ:
В версии 12.86 в мастере бизнес-процедур появилась функция
FormatFloat(<формат>, <число>),
где <формат> - текстовый параметр с маской форматирования, <число> - собственно число, которому нужно придать формат.
Например, значение FormatFloat("0.000", 66668/10000) - это текст "6.667" .

В более ранних версиях для форматирования числа в строку с 2-мя знаками после запятой предлагается пользоваться возможностями серверов.

MS SQL Server:
a = 180 (число, подлежащее записи в файл с 2-мя знаками)
q = SQL "SELECT STR(" + Str(a) + ", 30, 2) AS NUM"
oFile.Write(Trim(q.NUM))

Oracle: a = 180 (число, подлежащее записи в файл с 2-мя знаками)
q = SQL "SELECT TO_CHAR(" + Str(a) + ", '999999999999999999999999999999.99') AS NUM FROM DUAL"
oFile.Write(Trim(q.NUM))
Вопрос:
Возможно ли при выполнении SQL-запроса с помощью команды SQL или RunSQL обращаться не к базе KOMPAS, а к другой, например, KompasTMP? Вообще, задача более общая - в одном запросе использовать две базы данных, притом одна - MS SQL, а вторая - STANDARD (Paradox).

Ответ:
В существующем варианте Мастера бизнес-процедур в качестве DatabaseName всегда подставляется только KOMPAS. Возможность использования других баз данных за счет текста запроса возможна, но она разная в разных случаях:
  1. если KOMPAS - файл-серверная база данных, перед именем таблицы можно использовать любой псевдоним BDE, обрамленный двоеточиями, а всю конструкцию надо заключить в кавычки, например: ":KompasTMP:TEMP_M". Даже если указанная база данных расположена на сервере, такой запрос будет выполняться средствами самой BDE;
  2. если KOMPAS - база на сервере, то все сервера позволяют использовать таблицы из других баз данных того же сервера. В случае MS SQL для этого надо использовать конструкцию: <имя базы данных>.dbo.<имя таблицы>;
  3. во всех случаях вместо текста запроса в команде SQL можно использовать псевдоним запроса, записанного в QUERIES.DAT. В этом случае используется та база данных, которая указана в описании запроса. При этом действуют возможности 1 или 2, в зависимости от типа базы данных. Есть одно ограничение: псевдоним запроса вместе с именем группы не должен содержать пробелов. Вслед за псевдонимом запроса может быть расположен перечень значений параметров запроса - в том же порядке, в котором параметры представлены в описании запроса. Начиная с версии 10.72 между псевдонимом запроса и перечнем параметров можно вставить объект типа Список, в котором содержатся макропараметры.
Вопрос:
Как работает метод ServerFilter объекта "табличная форма"?

Ответ:
Свойство ServerFilter является свойством объекта класса "Набор данных", однако, использование этого свойства возможно только в том случае, если набор данных связан с какой-либо табличной формой:
  • созданной с помощью функции TForm;
  • полученной в качестве UsedObject при вызове бизнес-процедуры в качестве реакции на события табличной формы;
  • полученной в качестве UsedObject при вызове бизнес-процедуры по нажатию какой-либо кнопки табличной формы.
Значением свойства является текст, написанный по правилам языка SQL, который может быть использован в предложении WHERE запроса на выборку данных для табличной формы. Во избежание двусмысленности, рекомендуется все поля основной таблицы в тексте серверного фильтра снабжать префиксом "MAIN.". Любое изменение свойства ServerFilter приводит к перезагрузке данных в табличной форме. Если для свойства задано пустое значение, выборка данных при перезагрузке осуществляется без дополнительных условий. Иначе исползуется условие отбора, описанное в серверном фильтре.
Вопрос:
Поскажите, пожалуйста, как в бизнес-процедуре вызвать на экран окно с кнопками "ОК" и "Отмена"? Если пользователь нажимает "ОК", то работа продолжается, если "Отмена", то процедура завершается?

Ответ:
a=MessageBox "Сообщаю.","нажми кнопку"
if a then
      print "нажата кнопка ОК"
else
      print "нажата кнопка НЕТ"
end if

Вариант с отменой и выбором из списка:
Variants = "Вариант 1"+char(13)+"Вариант 2"
a = AskChoice("Выбор","Выберите вариант",Variants)
Вопрос:
Понятно, что для того, чтобы использовать в бизнес-процедурах хранимые процедуры, необходимо создать в Мастере запросов запрос, вызывающий эту хранимую процедуру, и потом командой RunQuery вызвать запрос. Но вот вопрос: можно ли использовать выходные параметры или результат выполнения (@PARAM OUTPUT, RETURN) процедур MSSQL? Например, рассчитал стажевые, все нормально - в процедуре MSSQL -> RETURN 0. Соответственно в бизнес-процедуре Компаса вывести сообщение "Всё нормально" и не возвращать набор данных (а записать в NARAD_M ). Если есть сотрудник, у которого не проставлен стаж, на него не рассчитались стажевые, то - в процедуре MSSQL -> RETURN 1 соответственно в бизнес процедуре Компаса вывести сообщение "Не нормально" (и вывести набор с таким(такими) сотрудниками для вывода в бизнес процедуре Компаса табельных номеров). Т.е., в процедуре MSSQL это реализовано, можно ли результат выполнения вытянуть в процедуру Компаса?

Ответ:
Для использования хранимых процедур в бизнес-процедуре (б/п) необязательно создавать запрос в мастере запросов: достаточно выполнить любым способом запрос "CREATE PROCEDURE <имя> ..." на сервере, а в тексте б/п использовать конструкцию RunSQL "EXEC <имя> <параметры>". Учитывая, что RunSQL (и RunQuery тоже) не возвращает никаких внутренних значений, взять значение выходного параметра в б/п не представляется возможным. Однако в MS SQL 2000 есть возможность создать хранимую функцию (CREATE FUNCTION). Вот ее-то результат вытащить можно:
CREATE FUNCTION <имя_функции> (<параметры>) RETURNS <тип_возвращаемого_значения> AS <тело_функции>
и в б/п: q = SQL "SELECT dbo.<имя_функции>(<значения_параметров>) AS FIELD1"
Print q.FIELD1
Более подробно о том, как писать хранимые функции, читайте в литературе по MS SQL 2000
Вопрос:
Как получить имя базы для бизнес-процедуры?

Ответ:
Имя текущей базы данных MS SQL - функция DB_NAME() самого сервера.
q = SQL "SELECT DB_NAME() AS BASENAME"
Print q.BASENAME
Вопрос:
Возникла проблема передачи параметров в бизнес-процедуру. Например:
текст бизнес процедуры "TEST" следующий:
       B=A@ARG
       PRINT B

в кнопке на табличной форме пишем программу
      A=120
      CALL "TEST",A
т.е. хочу передать в процедуру значение А.
Результатом нажатия на кнопку должно быть сообщение 120
Пишет ошибку в бизнес-процедуре не известное имя объекта A@ARG


Ответ:
Это делается вот таким образом:
Текст на кнопке
       A=120
       CALL "TEST_PARAM", A

Бизнес процедура "TEST_PARAM"
       A = @Arg[1]
       PRINT A
Вопрос:
Как из бизнес-процедуры запустить процедуру ORACLE? Меня интересует синтаксис строки.

Ответ:
RunSQL "..." - оператор вызова любого SQL-запроса, в т.ч. и вызывающего хранимые процедуры (EXECUTE ...)


Вернуться к главному перечню вопросов