Apico Soft / АПИКО Софт



Спонсором блога ScalaHelp.RU является компания АПИКО Софт.

Мы предоставляем:
- Качественный ERP консалтинг.
- Внедрение и сопровождение системы.
- Российские формы первичных документов, бухгалтерская и налоговая отчетность.

- Разработка корпоративной отчетности.

Наш телефон 8 (495) 961 98 48
Сайт http://www.apicosoft.ru/

Позвоните нам, мы сделаем все, чтобы помочь Вам.

понедельник, октября 29, 2007

Стандартные отчеты ERP Scala

Scala в своем составе имеет большое количество отчетов. Их можно условно разделить на отчетные формы и первичные документы.

К сожалению, логика и внешний вид большинства отчетных форм зашита в коде. При большом желании их тоже можно изменить, я даже видел такое решение - сделано было на основе постпроцессора. В двух словах: в настройках канала вывода указана программа (это и есть постпроцессор), Скала формирует отчет в виде текстового файла и запускает постпроцессор, передавая ему путь к файлу. Всего-то и остается написать программу, которая будет парсить файл и делать то, что вам нужно. Еще, как вариант, можно добраться до таких отчетов с помощью VBA, но это тоже будет разборка уже готового текста. В общем - мазохизм. Если уж требуется изменить такой отчет, то я бы лучше просто попробовал повторить его в виде внешнего отчета.

Но не все так плохо. Первичные документы можно менять в широких пределах. Для того, чтобы посмотреть список таких отчетов, запускаем команду "Системные Утилиты - Документы - Изменение Определения Документа - Редактор Формата Отчета". В дереве вверху слева дерево отчетов. В этом же окне, если выбрать отчет, то можно увидеть список кодов, которые можно использовать в этом конкретном отчете в разрезе секций.

Отчеты хранятся по пути \iScala\WinDS\Resources\Reports\. В ветке Standard\Модуль трогать ничего не надо, там лежат стандартные варианты. Свои наработки выкладываем в ветку Custom\Модуль.

Имя отчета

Формируется по правилу MMKKCCDDLLL.EXT, где:

  • MM - модуль (GL, PL, SL….)
  • KK - код документа внутри модуля
  • CC - код компании (документ с кодом компании 01 будет использоваться по умолчанию для всех компаний, если, конечно, для самой этой компании не определен свой документ)
  • DD - код документа (работает в случае, если в заголовке конкретного документа есть поле "Код документа", это поле будет определять какой из шаблонов брать, по умолчанию берется отчет с кодом 00)
  • LLL - код языка (ENG, RUS… - в iScala; 00, 01… - в Scala)
  • EXT - расширение файл зависит от типа отчета (DDF, RTF, RPT)

Например, GL040100RUS.DDF - Модуль GL, документ Cash Receipt/Приходный кассовый ордер, компания 01, код документа 00, язык русский, типа отчета DDF.

Сам отчет может быть сделан с использованием нескольких технологий. Какой конкретный вариант будет использоваться определяется настройками канала вывода. Дальше рассмотрим эти варианты.

DDF

Представляет из себя текстовый шаблон отчета. Отчет разбит на секции, список и порядок вывода секций изменить нельзя. Внутри секций используются коды полей для подстановки данных из системы. Имеется небольшой набор способов форматирования данных.

RTF

На самом деле это тоже DDF, и все правила подстановки полей там такие же. Просто внутри секции используется формат RFT, он ведь тоже текстовый. До iScala это был практически единственный способ сформировать красивый документ. При этом редактирование такого документа не самая простая задача. Если у вас iScala, то я бы избегал использования RTF отчетов. Единственный случай, когда это может быть оправдано, это унаследованные отчеты. Зачем ломать то, что работает? В остальных случаях я бы предпочел использовать Crystal Reports.

RPT

Это отчет на Crystal Reports. Здесь тоже без DDF не обошлось. Видимо для целей совместимости, такой отчет формируется в два этапа. Сначала отрабатывается специально заполненный DDF отчет, на основе его формируется набор данных(датасет), который и передается в RPT. Описание структуры передаваемых данных делается на основе TTX файла, этот файл необходим только во время дизайна отчета. RPT отчеты, на мой взгляд, сейчас самый удобный вариант для кастомизации, т.к. позволяют наиболее гибко настроить выходную форму.

вторник, октября 23, 2007

MS SQL: Отладка хранимых процедур, триггеров

Сегодня не совсем скальская тема. Но в любом случае, поддержка БД MSSQL составляет существенную часть работы администратора ERP системы Scala.

В MS SQL 2000 появилась возможность отлаживать хранимые процедуры. Правда отладчик был упрятан довольно далеко, в результате не все знают про его существование.

Для запуска хранимой процедуры под отладчиком нужно запустить Query Analyzer, приконнектиться к серверу, найти в Object Browser (если это окно не открыто, то нажмите F8) нужную процедуру. Щелкните на ней правой кнопкой мыши и выберите пункт Debug. Появится окно Debug Procedure - в нем нужно заполнить значения параметров процедуры, с которыми вы хотите ее запустить. После нажатия кнопки Execute вы попадет в отладчик. Возможности отладчика стандартные: пошаговое выполнение, проверка значений переменных, точки останова... Думаю тут ничего сложного.

С хранимыми процедурами понятно. А как быть, если нужно отладить, например, триггер? В этом случае есть одна хитрость - нужно сначала сделать хранимую процедуру, действия в которой приведут к выполнению триггера. После этого запускаем отладку этой вспомогательной процедуры, доходим пошагово до строки, зажигающей триггер, и жмем на ней кнопку Step Into (F11). В результате должен открыться текст триггера, а выполнение его остановится на первой строке - то, что нам и было нужно. Я думаю, что такой же фокус пройдет и с функцией, каюсь, сам не пробовал.

В MS SQL 2005 функциональность отладки была существенно переработана. Теперь для отладки нужно использовать Visual Studio. Причем версии Express Edition и Standard для этого не подойдут, только Professional и Team. Правда, все стало проще - в окне Server Explorer щелкаем правой кнопкой мыши на любом объекте БД (хранимой процедуре, триггере, функции), выбираем из локального меню пункт Step Into… и попадаем в отладку. Причем, отлаживать можно как хранимые процедуры, написанные на T-SQL, так и на C# или VB.NET.

Попробовал воспользоваться для отладки процедуры на 2005м сервере Query Analyzer из 2000го - ругается [SQL-DMO]You must use SQL Server 2005 management tools to connect to this server.

UPDATE: Ситуация с отладчиком улучшилась с выходом MS SQL 2008. Теперь запускать отладку можно непосредственно из MS SQL Server Management Studio. Просто в окне редактирования запускаем скрипт через ALT+F5. Доступны стандартные методы отладки.

вторник, октября 16, 2007

Синхронизация справочников учетных измерений

Довольно часто в Scala заводится две компании - одна для российского и одна для западного учета. В этом случае справочники учетных измерений могут существенно совпадать. Получается, что нужно заводить, редактировать и удалять новые значения сразу в нескольких места. Это не очень удобно.

Существует несколько способов решения. Например, можно сделать SQL-скрипт, который будет синхронизировать нужные справочники и регулярно запускать его (руками либо запланировать job). Еще можно сделать триггер, который будет выполнять такую работу. Вот и займемся созданием такого триггера.

Текст триггера (проверено iScala 2.2 SR1):

create trigger GL03SYNC_ ON [dbo].[GL03]
for insert, update, delete
as

begin

set nocount on

declare @DelCount int, @InsCount int, @DimList as nvarchar(100)

-- список УИ, все 'BCDEFGHIJ'
set @DimList = 'BCDE'

select @DelCount = count(*) from deleted
select @InsCount = count(*) from inserted

-- Update
if @DelCount > 0 and @InsCount > 0
begin
update s set
GL03001 = i.GL03001, GL03002 = i.GL03002, GL03003 = i.GL03003, GL03004 = i.GL03004, GL03005 = i.GL03005,
GL03006 = i.GL03006, GL03007 = i.GL03007, GL03008 = i.GL03008, GL03009 = i.GL03009, GL03010 = i.GL03010,
GL03011 = i.GL03011, GL03012 = i.GL03012, GL03013 = i.GL03013, GL03014 = i.GL03014, GL03015 = i.GL03015,
GL03016 = i.GL03016, GL03017 = i.GL03017, GL03018 = i.GL03018, GL03019 = i.GL03019, GL03020 = i.GL03020
from GL03 s
join inserted i on i.GL03001 = s.GL03001 and i.GL03002 = s.GL03002
where charindex(i.GL03001, @DimList) > 0
end

-- Delete
if @DelCount > 0 and @InsCount = 0
begin
delete s
from GL03 s
join deleted i on i.GL03001 = s.GL03001 and i.GL03002 = s.GL03002
where charindex(i.GL03001, @DimList) > 0
end

-- Insert
if @DelCount = 0 and @InsCount > 0
begin
insert into GL03
select * from inserted i where charindex(i.GL03001, @DimList) > 0 and not exists
(select * from GL03 s where i.GL03001 = s.GL03001 and i.GL03002 = s.GL03002)
end

end

В приведенном тексте нужно:


  • Заменить <C1> на код компании-источника
  • Заменить <C2> на код исходной компании-приемника
  • Заменить <YY> на финансовый год (2 символа)
  • Отредактировать список учетных измерений, подлежащих синхронизации - переменная @DimList

Триггер требуется повесить на все таблицы GL03 в компаниях-источниках (обычно компания российского учета). При заведении нового года нужно не забывать добавлять и новый триггер.

После установки триггера, все операции в синхронизируемых справочниках желательно проводить только в компании-источнике, иначе возникнет расхождение.

среда, октября 10, 2007

Заполняем параметр отчета из VBA

Задача: в любом стандартном отчете(Crystal Reports) получить возможность добавлять расшифровку подписи директора и главного бухгалтера.
Начнем с хранения расшифровок. Заведем для этого несвязанную UDDB таблицу (компание-независимая, годо-независимая) Params:

Заполняем таблицу (считаем что ID для директора DIR, а для главного бухгалтера GLBUH):

Добавляем новый VBA проект. Он будет срабатывать при запуске печати, просматривать отчет и, если в отчете есть параметры DIR или GLBUH, то заполняет их соответствующими значениями из UDDB таблицы. В новом проекте делаем двойной щелчок на ThisProcess, в открывшемся окне редактора вставляем код:

'   Declare the report engine to access its events
Dim WithEvents m_rptEngine As ScaPrintEngine.ScaReportEngine
Dim dctDict As New Scripting.Dictionary

Private Sub m_rptEngine_ReportBeforePreview(ByVal Report As ScaPrintEngine.IScaReport, PreviewReport As Boolean)
Dim crParamDef As CRAXDRT.ParameterFieldDefinition
Dim crParamDefs As CRAXDRT.ParameterFieldDefinitions

Set crParamDefs = Report.NativeReport.ParameterFields
For Each crParamDef In crParamDefs
With crParamDef
If dctDict.Exists(.ParameterFieldName) Then _
.SetCurrentValue dctDict(.ParameterFieldName)
End With
Next crParamDef
End Sub

Private Sub ScaProcessPI_ActionStart(ByVal ActCode As String, _
ByVal MenuParam As String, ByVal ActType As Long, ByVal ActParam As Variant)
' Initialise the report engine member on action start
Set m_rptEngine = ThisProcess.Reporter
End Sub

Private Sub m_rptEngine_NewReport(ByVal Report As ScaPrintEngine.IScaReport)
' Save action code in the report name
Report.Name = ThisProcess.ActionCode

Dim objConnection As New ADODB.Connection
Dim objCommand As New ADODB.Command
Dim objRs As New ADODB.Recordset

objConnection.ConnectionString = ThisProcess.UserContext.GetConnectionString(scaADO)
objConnection.Open
objCommand.CommandText = "select ID, Value from Params0000 where CompanyCode = '" _
& ThisProcess.UserContext.CompanyCode & "'"
Set objCommand.ActiveConnection = objConnection
objCommand.CommandType = adCmdText
Set objRs = objCommand.Execute

dctDict.RemoveAll
Do While Not objRs.EOF
dctDict.Add RTrim(objRs.Fields("ID").Value), RTrim(objRs.Fields("Value").Value)
objRs.MoveNext
Loop

objRs.Close
objConnection.Close

Set objRs = Nothing
Set objCommand = Nothing
Set objConnection = Nothing

End Sub




Добавляем недостающие ссылки:





Переводим проект в глобальный.



Все. Добавляем в любой стандартный отчет параметры DIR и GLBUH, кидаем их на форму. Значения, если все сделано правильно, заполнятся автоматически при печати.






Список параметров можно расширять только добавляя записи в Params, в коде исправления не потребуются. Пример набросал прямо сейчас, так что ошибки могут быть, но как отправная точка подойдет.

пятница, октября 05, 2007

ГТД в информации о партии

Специального поля под ГТД (Грузовая Таможенная Декларация) в Scala нет. Хранить эту информацию уместнее всего в партии. Проще всего отвести для ГТД одно из полей пользователя партии.

Запускаем команду "Управление Запасами - Прочее - Настройка - Параметры". Идем на закладку 3 "Поля пользователя в партии", выбираем незанятое поле - в моем случае второе. В первом поле пишем название - "ГТД", второе поле "Нет", если не хотим проверки по справочнику. Если же проверка требуется, то ставим "Да" и дополнительно заполняем соответствующий справочник, не забывая поддерживать его в актуальном состоянии ("Управление Запасами - Прочее - Настройка - Файлы кодов - ГТД").

При выборе поля для ГТД нужно учесть, что максимальная длинна полей пользоватея партии разная:

  1. 20
  2. 10
  3. 10
  4. 8
  5. 8
  6. 4
  7. 4
  8. 2
  9. 2
  10. 1

Трудно сказать с чем связан такой разнобой. Размер самого ГТД не лимитирован. Лучше всего подходит поле 1, т.к. оно самое длинное, как вариант можно  использовать два поля.

Если такой размер полей не устраивает, то можно хранить ГТД в дополнительном описании партии. Например, в первом поле текста. Размера в 70 символов гарантированно хватит. Дополнительно нужно сделать процесс введения ГТД удобным. Дело в том, что при настройках по умолчанию окно ввода текста партии не появляется. Для изменения этого поведения нужно запустить команду "Управление Запасами - Прочее - Дополнительные Параметры", закладка 2, параметр "Ввод текста о партии при поступлении" = Да. Минусом данного способа является неудобство при выводе в DDF.