Pull to refresh

VBscript в помощь 1С-программисту

Reading time3 min
Views6K
Недавно получил ТЗ на разработку несложного отчета с выводом результатов в файлы. Ничего необычного, кроме нескольких пунктов:
  1. Результат работы отчета должен будет отсылаться по расписанию специальной утилитой от стороннего разработчика
  2. Все должно работать в полностью автоматическом режиме
  3. Изменения в конфигурацию вносить нельзя

Если бы не пункт 3, то наверняка реализовал бы довольно распространенным способом: включил отчет в конфигурацию, в модуль приложения добавил выполнение отчета при входе специального пользователя с определенным именем. Соответственно, перед запуском сторонней утилиты настроил бы запуск 1С из командной строки под учетной записью этого специального пользователя. Но…


Практически вся первоначальная реализация идеи (простенький VBScript, который, используя OLE Automation, подключает COM-объект приложения 1С и инициирует выполнение внешнего отчета) отражена в процедуре Execute() представленного ниже кода. Все остальное было написано в порыве «сделать красиво» и облегчить жизнь себе и другим: настройки оформлены отдельным блоком с переменными, ошибки выполнения обрабатываются и записываются в лог-файл с указанием кода, описания и источника ошибки.
On Error Resume Next

Dim ComApp, ExtProc, Path, Dest, LogName, ExtRep, ConnectionString

'Строка подключения к ИБ
ConnectionString = "Srvr=APPSERVER;Ref=base"
'Папка назначения для файлов отчета
Dest = "D:\Out\"
'Получаем папку скрипта
Path = LEFT(WScript.ScriptFullName, InStrRev(WScript.ScriptFullName,"\"))
'Полный путь к лог-файлу
LogName = Path & "errors.log"
'Полный путь к внешнему отчету
ExtRep = Path & "extreport.erf"

Execute()
CheckErr()
Set ExtProc = Nothing
ComApp.Exit(False)
Set ComApp = Nothing

Sub Execute()
  Set Connector = CreateObject("V81.ComConnector")
  Connector.Connect(ConnectionString) 'Будет исключение, если база недоступна
  Set ComApp = CreateObject("V81.Application")
  ComApp.Connect(ConnectionString)
  Set ExtProc = ComApp.ExternalReports.Create(ExtRep)
  ExtProc.Path = Dest
  ExtProc.Service = Path
  ExtProc.Code = "42"
  ExtProc.Exec()
End Sub

Sub CheckErr()
  If Err.Number = 0 Then Exit Sub
  Set FS = CreateObject("Scripting.FileSystemObject")
  Set LogFile = FS.OpenTextFile(LogName, 8, True)
  LogFile.WriteLine(Now & " (" & Err.Number & ") " & Err.Description & " - " & Err.Source)
  LogFile.Close
  Err.Clear
End Sub

* This source code was highlighted with Source Code Highlighter.


Когда писал скрипт, то столкнулся с двумя неочевидными для меня моментами.
Первый – это обработка исключительных ситуаций без привычных try … catch.
Немного «помучив» по этому поводу MSDN обнаружил, что если указать инструкцию On Error Resume Next то управление будет передаваться на следующую строку, после той, в которой возникла ошибка. А если ошибка возникает в теле процедуры, то управление передается на строку следующую за вызовом процедуры.
Таким образом, поместил весь основной код в процедуру Execute(), а исключения решил отлавливать процедурой CheckErr().
Второе – это «зависание» выполнения скрипта, если информационная база отсутствует.
Точнее при отсутствии базы COM-приложение показывает диалоговое окошко с сообщением об ее отсутствии и ждет реакции пользователя. Но согласно ТЗ пользователь не увидит этого и процесс будет «висеть»… Здесь меня спас COMConnector, который вызывает исключение в случае проблем с соединением, вместо отображения диалоговых окон, и в начале кода процедуры Execute() появились еще две строки.

Здесь Set ExtProc = ComApp.ExternalReports.Create(ExtRep) создается экземпляр COM-объекта для внешнего отчета с помощью обращения к менеджеру ВнешниеОтчеты по его английскому синониму.
Далее инициализация параметров отчета и запуск на исполнение.

Написание внешнего отчета 1С выходит за рамки этого топика, но нужно сделать одно важное замечание: реквизиты отчета, экспортные функции и процедуры, которые вы хотите сделать доступными Automation-клиенту, должны именоваться по-английски, иначе к ним нельзя будет обратиться из VBScript.

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

Теперь осталось поместить в cmd-файл вызов скрипта и утилиты отправки, и… цель достигнута – все работает и все согласно ТЗ.
Tags:
Hubs:
+1
Comments2

Articles