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



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

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

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

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

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

вторник, декабря 25, 2007

iScala hardware requirements

Периодически встает задача порекомендовать конфигурацию компьютеров для Scala. Если с рабочими станциями все достаточно стандартно, то с сервером обычно не все так просто. Для начала глянем в дистрибутив iScala 2.3 и посмотрим, что рекомендует Epicor.

We recommend having a dedicated server for the installation of DBMS and iScala 2.2 SR2 with HF3062.

Recommended configuration for communities of up to 50 users:

  • Dual Pentium III - 1 GHz or faster processor system (Dual Xeon - 3 GHz is preferable but not mandatory, at the time of the current release: Spring 2004)
  • 1024 MB RAM or more (4GB is preferable but not mandatory)
  • Hardware RAID-1 for OS, DBMS and iScala binaries (2GB for the DBMS and iScala installation)
  • Hardware RAID-5 with 6 spindles for iScala databases (at least 1GB for the initial installation)
  • 100Mb network connection
  • DVD-ROM drive

    Сразу видно, что рекомендации не корректировали давно, даже номер версии не исправлен. Хотя по большому счету все довольно правильно, нужно только немного подкорректировать некоторые цифры. Далее речь идет о сервере начального уровня, условно до 50 пользователей.

    CPU

    Думаю, оптимальным сегодня будет один двуядерный Xeon.

    RAM

    4GB. Можно поставить и больше, но Windows Server 2003 Standard Edition поддерживает максимально 4GB, а покупать версию Enterprise для сервера начального уровня, наверно, излишне.

    HDD

    На серверах по возможности лучше использовать SCSI диски. RAID же считаю обязательной частью нормального сервера. HotSwap (горячая замена, без остановки сервера) не обязательно, я вот просто почему-то боюсь их дергать прямо во время работы и все равно сначала выключаю.

    Приведенная выше конфигурация очень практична. На первый раздел ставим систему. Сам раздел создаем из двух дисков, объединенных в RAID1 (зеркалирование). Большой объем для этого раздела не требуется, достаточно 70-80GB.

    Второй раздел для данных. Тут удобнее использовать RAID5. В этом случае немного проигрываем по скорости записи (на хорошем контроллере разница должна быть несущественной), но выигрываем по времени чтения. Для сервера начального уровня будет достаточно трех дисков (в RAID5 может быть от 3 до 6 дисков). При этом мы жертвуем размером одного диска. Большие диски для этого раздела тоже не обязательны, т.к. могут серьезно поднять стоимость системы. Если, предположим, вы будете использовать три диска объемом 100GB, то получите раздел объемом 200GB. Для рабочих данных вполне достаточно, особенно, если бекапирование делается на другие диски.

    Сервер

    Конечно, лучше от нормального производителя - HP, Dell, IBM…

    Конструктив удобнее для монтажа в 19 дюймовую стойку, но это уже определяется системным администратором. Еще нужен UPS и не надо забывать делать поправку на время.

    UPD: В текущем хотфиксе требования исправлены:

    Server Hardware

    Communities of up to 50 Users

    We recommend having a dedicated server for the installation of DBMS and iScala 2.3.

    Recommended configuration for communities of up to 50 users:

    Dual Xeon - 3 GHz or better
    2 GB RAM or more (4GB is preferable but not mandatory)
    Hardware RAID-5 for OS, DBMS and iScala binaries (2GB for the DBMS and iScala installation)
    Hardware RAID-5 with 6 spindles for iScala databases (at least 1GB for the initial installation)
    Gigabit network connection
    DVD ROM drive

    четверг, ноября 29, 2007

    iScala VBA: Встроенные формы

    Чаще всего при создании новой формы средствами VBA используют стандартные компоненты. В результате форма выглядит достаточно инородно:

    В составе Scala идет набор своих компонентов - туннелированные компоненты, позволяющих встраивать VBA приложения без всяких швов. Сделаем простейшую форму.

    1. Создаем новое VBA приложение Tunneling: Tools -> VBA Developer -> Project Explorer. New Project. Set Active для нового приложения.
    2. Идем в среду разработки: Tools -> VBA Developer -> Visual Basic Editor
    3. Добавляем новую форму.
    4. Идем в Tools -> References и добавляем ссылку на ScaXVBProxies 1.0 Type Library
    5. На палитре компонентов Toolbox щелкаем правой клавишей мыши и выбираем Additional Controls. Отмечаем все ScaXVB* компоненты. Получится что-то вроде этого:
    6. Бросаем на форму ScaXVBForm. Он должен присутствовать на любой форме, где используются туннелированные компоненты.
    7. Рисуем фому, используя только скальские компоненты. Добавляем кнопку закрыть с кодом ScaXVBForm1.DelayUnload
    8. Добавляем событие ScaXVBForm1_OnScaReady. В этом событии нужно заполнить все заголовки на форме. Дело в том, что вы не сможете сделать это в дизайнере, т.к. по идеологии таких приложений они должны читать все строки из LAN-файлов. По уму и нужно создать пользовательский LAN-файл и читать строки оттуда, но для простоты я сделал это в коде.
    9. Добавляем кнопку для запуска (в меню добавляется аналогично):

    Получаем стандартную встроенную форму:

    Код примера.

    ' Файл UserForm2

    Private Sub scaXVBButton1_OnScaClick()
    ScaXVBForm1.DelayUnload
    End Sub

    Private Sub ScaXVBForm1_OnScaReady()
    scaXVBLabel1.Caption = "Some Label 1:"
    scaXVBLabel2.Caption = "Some Label 2:"
    scaXVBLabel3.Caption = "Some Label 3:"
    scaXVBButton1.Caption = "Close"
    End Sub

    ' Файл ProjectMacros

    Sub RunUserForm2()
    UserForm2.ScaXVBForm1.Connect ThisProcess, scaXVBDockedForm
    UserForm2.ScaXVBForm1.Show
    End Sub

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

    Расширение функциональности Scala/iScala.Внешние программы. На чем писать.

    Рано или поздно встает вопрос написания внешних программ, для целей отчетности или дополнительной функциональности. Вот на выборе среды, в которой можно это сделать, и остановлюсь сегодня. Исходить буду из то, что нужно решение, которое легко освоить, недорогое (в идеале бесплатное). Поэтому я сразу отбросил C++, да и C# решил не упоминать.

    Visual Basic 6 (VB6)

    Очень простая среда программирования, легкая в освоении и понятная, правда немного устаревшая и я не уверен, что Microsoft еще продает лицензии на этот продукт. Если у вас уже освоен VBA, то особых проблем при переходе не будет. Скорее всего еще долго будет использоваться.

    Delphi

    http://www.codegear.com/

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

    Access

    Я не любитель этого продукта, хотя честно несколько раз брался за него. Похоже не мое. Но уже неоднократно видел кучу функциональности для Scala, написанной на Access. В общем попробовать его стоит, свои задачи он решает.

    Visual Basic 2005 Express Edition

    http://www.microsoft.com/rus/msdn/vstudio/express/default.mspx

    Это бесплатный вариант Visual Studio. Никаких лицензионных ограничений. Функциональные ограничения несущественны для простых разработок. Современная, удобная среда, с полным набором возможностей. Для запуска приложений требуется установленный .Net Framework 2.0, но он устанавливается вместе с iScala 2.3. Для более ранних версий придется поставить его руками. Буквально на дня вышел Visual Basic 2008 Express, но его я еще не смотрел. Думаю, что тоже будет достойный продукт.

    SharpDevelop

    http://www.icsharpcode.net/OpenSource/SD/

    Бесплатная среда для разработки программ под .Net Framework с открытыми исходными кодами. Возможности шире, чем у VB Express, работает довольно стабильно. Мне его использовать в реальных проектах не приходилось, но рассмотреть его как вариант стоит.

    Вывод

    На чем остановиться нужно решить самому. У меня это VB6 для быстрых и простых задач и VB Express в остальных случаях.

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

    MS SQL: Backup всех БД

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

    Запускаем Enterprise Manager. Выбираем в дереве "Management/Database Maintenance Plan" . Команда "New Maintenance Plan...". Запускается визард. Дальше, если картинки нет, то соответствующие окна пропущены и в них менять ничего не нужно.

    Выбор баз данных. Можно выбрать все, только системные, все кроме системных, указать конкретных список БД.

    Здесь включаем бекап и, нажимаем на отмеченную кнопку.

    Расписание запуска. В моем случае сделан запуск после каждого рабочего дня.

    Указываем куда помещать файлы бекапов и нужно ли для каждой базы создавать свой подкаталог. Еще очень удобно, что можно указать сколько времени хранить, т.е. кроме самой процедуры резервного копирования, будут еще стираться старые файлы (тут бы я еще предусмотрел еще одну отдельную процедуру, которая, например, в выходные будет копировать текущие резервные копии на ленточку или другой сервер).
    Логи и оповещение оператора.
    Ну вот и все. Задаем имя для плана и сохраняем. Все сделано на примере 2000й версии. В 2005м никаких принципиальных отличий нет. Запускаем Management Studio. Путь "Managements/Maintenance Plans". Команда "Maintenance Plan Wizard".

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

    DDF отчеты

    DDF отчеты самая старая технология создания отчетов в Scala. Такой отчет представляет из себя текстовый файл. Файл является шаблоном отчета, где описано содержание всех секций, состав секций и последовательность их вывода жестко зашиты в коде, так что повлиять можно только на содержимое самих секций. Для примера можно взглянуть на довольно простой отчет OR06 Product Label:

    :START-LABEL
    ╔═════════════════════════════════════╗
    ║ <805> ║
    ║ <806> ║
    ║ STOCK.COD: <804L25> ║
    ║ DEL.DATE : <615> QTY :<811R09> ║
    ║ ORDER : <04> POS : <801> ║
    ║ BUYER : <401L25> ║
    ║ CUSTOMER : <400> ║
    ║─────────────────────────────────────║
    ║ <86> ║
    ╚═════════════════════════════════════╝
    :END-LABEL
    0
    2

    Тут всего одна секция LABEL. Угловыми скобками выделены макросы. Коды полей можно посмотреть здесь: "Системные Утилиты - Документы - Изменение Определения Документа - Редактор Формата Отчета", предварительно выбрав нужный отчет. Например, макрос <804L25> означает следующее: 804 - код запаса,  L25 - взять 25 символов слева. Менять можно только содержимое внутри секций. Значения вне секций трогать не советую(в нашем примере это две последние строки), там часто бывают всякие настройки, без которых сам отчет будет работать некорректно.


    Какие еще преобразования возможны в DDF файлах? В хелпе я не нашел полного описания. У меня откуда-то давно есть текстовый файлик. Правда, не все, что описано в нем удалось использовать, но несколько раз он мне очень помог, так что приведу его здесь полностью:

    -------------
    DDF processor
    -------------

    Start [Prefix] DDFCode [Selector] [Modifier]... [Language] [;] End

    Start < Start of DDF Code

    Prefix # Optional Prefix
    D (1) Date in words format (old style)
    ! (1) Date in words format (old style)
    $ (2) Amount in words format
    Z (3) Old Amount in words Format
    * (4) Leading ***
    _ (5) Russian dash delimiter ("12.12" like "12-12")
    = (6) Russian truncate decimals ("12.00" like "12=")
    . (7) Numbers with "." delimiter
    : (8) Trimming of spaces before formating

    DDFcode ## DDF code
    ###
    ?## Extended DDF Code
    ?###
    ??###

    Selector L## Left part selector
    L###
    R## Right part selector
    R###
    S##@## Substring,Length
    S###@##
    S##@###
    S###@###

    Modifier(s) /* To Currency Recalculation modifier
    /?
    /##
    :* From Currency Recalculation modifier
    :?
    :##
    .# Rounding modifier
    -# Coding segment,Length
    +## Price from Price List

    Style @# Date style (Numeric format):
    0 - Scala standard/2 digit year)
    1 - Scala extended/4 digit year)
    2 - Compressed(No delimiters)/2 digit year
    3 - Compressed/4 digit year
    4 - ISO 8601 (always YYYY-MM-DD)

    @# Date Style (Date in word Format)
    @* Output Currency Style (Amount in word format)
    @?
    @##

    Language ??? Language
    FitFlag ; Example w/o fit: 12345678901234567890
    DDFCode=XXX 1234567890XXX 1234567890
    DDFCODE=XXXXXXXXXXXX 1234567890XXXXXXXXXXXX4567890
    Example with fit: 12345678901234567890
    DDFCode=XXX 1234567890XXX12346567890
    DDFCODE=XXXXXXXXXXXX 1234567890XXXXXXXXXXXX1234567890

    & Equivalent to fit plus additionally substitutes XML internal entities
    & -> &amp;
    < -> &lt;
    > -> &gt;
    ' -> &apos;
    " -> &quot;
    & prevent ANSII2OEM conversion of DDF Code as well
    \ Equivalent to fit without trimming spaces
    Example with fit: 12345678901234567890
    DDFCode=XXX 1234567890XXX 12346567890
    DDFCODE=XXXXXXXXXXXX 1234567890XXXXXXXXXXXX1234567890

    > End of DDF Code

    На что стоит обратить внимание:



    • операции над строками, <CodeL10> - взять 10 символов слева, <CodeR15> - взять 15 символов справа, < CodeS10@12> - подстрока 12 символов, начиная с 10го
    • разные варианты заполнения <Code>, <Code;>, <Code\>

    понедельник, октября 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.

    вторник, сентября 25, 2007

    RGW плюсы и минусы использования

    RGW - генератор отчетности. Автор Рушан Абдряшитов. Проект родился не внутри R&D, а скорее от недостатка средств отчетности для консультантов при внедрении. Это один из немногих внешних генераторов отчетов, заточенных под Скалу. Позволяет делать несколько типов отчетов:

    1. Отчет на основе окошек. Окошко в данном случае - это ячейка в шаблоне отчета, в которой прописаны правила расчета суммы в этой ячейке. Что-то вроде этого:По такой схеме удобно, например, делать балансовые формы. Образец такой формы есть в дистрибутиве RGW. Не требуется знать ничего о структуре базы данных, просто описываем правила расчета бухгалтерским языком.
    2. Формирование выборки по произвольному SQL запросу. В тексте запроса можно использовать макросы CC, YY, Period1, Period2 (Код компании, финансовый год, дата начала периода и дата конца периода соответственно). Запрос может быть только один, поддерживается группировка по одному полю.
    3. Корреспонденция счетов. В генератор встроен механизм, который в полуавтоматическом режиме, пытается привести многострочные проводки Скалы к виду дебет-кредит. Я обычно пытаюсь отговорить от использования корреспонденции, раз уж выбрана Scala. Если без этого никак, то другого готового способа, кроме как RGW, я не знаю.
    4. Запуск отчетов Crystal Reports. Для использования под RGW отчеты требуют небольших правок. Следует учитывать, что начиная с версии iScala 2.3 имеется возможность вставлять RPT отчеты непосредственно в меню Скалы.

    Плюсы RGW:

    • Простая возможность создавать отчеты своими силами, не прибегая к услугам консультантов
    • Корреспонденция счетов
    • Excel как основа для шаблоном, так и выходной формат

    Минусы:

    • После установки RGW Excel в некоторых ситуациях начинает вести себя не совсем привычным способом
    • Нельзя встроить отчеты в меню Скалы

    Стоит ли покупать RGW? Насколько я знаю, российским клиентам могут предложить этот генератор при продаже лицензии в нагрузку - берите, пусть будет. Если же требуется платить за него отдельно, то решайте сами.

    Думаю, что не будет преступлением, если я выложу здесь инструкцию пользователя RGW. Она поможет оценить, что может этот генератор. Скачать инструкцию.

    среда, сентября 19, 2007

    Заголовки полей

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


    В таких случаях для удобства пользователей стоит изменить заголовок поля. Предположим, что хотим заменить заголовок "Текст" на форме ввода счетов-фактуры в Книге Закупок. Новый заголовок будет "Основание". Исхожу из того, что основной язык русский. Что имеем на данный момент:

    Как это сделать:

    1. Определяем имя формы. Для этого открываем нужную форму и смотрим на статусную строку Скалы.
      Значит имя формы PL0030
    2. Редактируем LAN-файл. В LAN-файлах хранятся строки, являющиеся заголовками полей, сообщениями об ошибках. Для каждого языка свой файл. Запускаем iScala Administration Console. Идем в раздел Языки - Строки LAN файлов - RUS - PL - PL0030. На последнем пункте щелкаем правой кнопкой и выбираем команду "Редактировать". В правой панели ищем исходную строку. У меня она под номером 101 (iScala 2.2 SR1 в других версиях Scala это может отличаться) и заменяем "Текст" на "Основание". Снова вызываем локальное меню на пункте PL0030 и выбираем команду "Сохранить". Теперь в дереве будет вместо PL0030 написано PL0030(Польз.). Это означает, что был создан пользовательский вариант LAN файла.
    3. Проверка. Запускам команду ввода счетов-фактур и видим результат:

    Но этим способом можно воспользоваться не на всех формах. Часть форм выполнена описывается SDF файлами, в этом случае в LAN файлах заголовков полей нет, они хранятся непосредственно в в SDF файле. Приведу пример смены заголовка и в такой форме. Предположим мы хотим переименовать заголовок поля "Ссылка" на форме ввода/корректировки поставщика. Предполагается, что Скала установлена на диске C: в каталог по умолчанию. Для этого нужно сделать следующее:

    1. Подсматриваем имя формы - PL0010
    2. Находим файл C:\Program Files\Scala Business Solutions NV\iScala\WinDS\Resources\FormsSDF\Standard\RUS\PL\pl0010x.sdf и копируем его в каталог C:\Program Files\Scala Business Solutions NV\iScala\WinDS\Resources\FormsSDF\Custom\RUS\PL\
    3. Открываем на редактирование файл pl0010x.sdf в ветке Custom. Находим в разделе [Fields] нужный заголовок и изменяем его
    4. Проверка. Запускам нашу форму и убеждаемся, что заголовок изменился.

    Кроме корректировки заголовков полей, SDF файлы позволяют в небольших пределах изменять сами формы. Если, например, найти по заголовку нужное поле и удалить эту и следующую строку, то это поле не будет отображаться на форме. Правда делать такие эксперименты нужно осторожно.

    четверг, сентября 13, 2007

    Типы проводок

    В поле GL06012 указывается тип проводки. Это бинарное поле, для удобства его преобразовывают convert(char(1), GL06012). Ниже приводится список кодов (коды приведены как в буквенном, так и в бинарном виде):

    • / - 0x2F - Входящее сальдо
    • 0 - 0x30 - Проводка ГК (прямой ввод)
    • 1 - 0x31 - Сторно в ГК
    • 2 - 0x32 - Периодическое распределение / переоценка валютных счетов
    • 3 - 0x33 - Счет покупателя (КП)
    • 4 - 0x34 - Платеж покупателя (КП)
    • 5 - 0x35 - Счет поставщика (КЗ)
    • 6 - 0x36 - Платеж поставщика (КЗ)
    • 7 - 0x37 - Амортизация ОС (из модуля ОС)
    • 8 - 0x38 - Автораспределение (периодические: 51-99)
    • 9 - 0x39 - Проводка модуля Управление Проектами
    • A - 0x41 - Проводка модуля Зарплата
    • B - 0x42 - Проводка модуля Управление Запасами
    • C - 0x43 - Проводка модуля Долговые Обязательства
    • D - 0x44 - Проводка модуля Касса (ГК)
    • K - 0x4B - Переоценка ОС
    • L - 0x4C - Книги Выверки (ГК)
    • S - 0x53 - Проводка из другой компании при консолидации
    • T - 0x54 - Временные проводки по чекам в ГК (только в журнале ГК)
    • U - 0x55 - Бюджет 1
    • V - 0x56 - Бюджет 2
    • W - 0x57 - Бюджет 3
    • X - 0x58 - Бюджет 4
    • Y - 0x59 - Бюджет 5
    • Z - 0x5A - Бюджет предыдущего года
    • \ - 0x5C - Входящее сальдо по проводкам отчетного уровня
    • a - 0x61 - Проводка по отчетным уровням
    • c - 0x63 - Проводка по отчетным уровням Бюджет 1
    • d - 0x64 - Проводка по отчетным уровням Бюджет 2
    • e - 0x65 - Проводка по отчетным уровням Бюджет 3
    • f - 0x66 - Проводка по отчетным уровням Бюджет 4
    • g - 0x67 - Проводка по отчетным уровням Бюджет 5
    • h - 0x68 - Проводка по отчетным уровням Бюджет предыдущего года
    • i - 0x69 - Проводка закрывающего периода
    • j - 0x6A - Проводка по отчетным уровням закрывающего периода
    • | - 0x7C - Перенесенное входящее сальдо по валютным счетам

    Спасибо за список пользователю Jugulator с форума "скалолазов".

    среда, сентября 05, 2007

    Что такое RSS

    Если вы регулярно просматриваете хотя бы несколько сайтов, то вам просто необходимо знать о RSS-лентах новостей. Что же это такое? Это стандартный способ оформления всего нового, что появилось на сайте. Самое главное слово здесь СТАНДАРТНЫЙ, оно позволило возникнуть новому классу программ - RSS агрегаторам. Такая программа кардинально меняет способ слежения за новинками в сети. Вместо того, чтобы проверять случайным образом, вы просто собираете в своем агрегаторе ссылки на сайты, блоги и т.д., к которым вы неравнодушны. При запуске проверки вы видите список всего, что есть нового в собранных лентах новостей. Это очень экономит время, да и не пропустите ничего важного.

    Как теперь выглядит общение с интернетом? Приходим на работу, запускаем агрегатор и видим все, что появилось на сайтах, за которыми мы следим. В процессе чтения новостей или захода на новые сайты вдруг натыкаемся на новый многообещающий ресурс - ищем там ссылку на ленту новостей и добавляем в агрегатор. Раз в одну-две недели просматриваем списки и удаляем то, что не оправдало надежд.

    Осталось выбрать агрегатор. Раньше я пользовался программой RssBandit http://rssbandit.org/. Удобный агрегатор с полным набором возможностей. Но в последнее время переехал на Google Reader http://www.google.com/reader/. Это не совсем программа, это скорее сайт-агрегатор, но сделан он так, что этого не замечаешь. Зато получаешь кучу плюсов, например, не важно с какого компьютера ты заходишь, все что нужно, хранится на сайте. В общем - советую. Не буду пытаться описать использование во всех подробностях, вы и сами не глупые люди, разберетесь, только не торопитесь с выводами - на Google Reader я переходил 3 раза прежде чем остался на нем.

    К чему я это? Ах да - ссылка на RSS-ленту моего сайта http://feeds.scalahelp.ru/scalahelpru. Именно эту ссылку нужно скормить вашему любимому агрегатору.

    среда, августа 29, 2007

    Учетная строка

    Учетная строка включает в себя счет и до девяти учетных измерений. Длина любой из частей не может превышать 12 символов.

    Я уже затрагивал эту тему в предыдущем посте, но решил вернуться, ведь разбирать учетную строку на части в запросах приходится часто и довольно быстро надоедает вспоминать ее раскладку.

    Можно облегчить себе задачу, если создать в базе набор функций, каждая из которых будет возвращать нужное учетное измерение. В результате вместо substring(GL06001, 13, 6) можно будет писать dbo.Dim1(GL06001). В добавок отчеты, сделанные с использованием таких функций можно будет без проблем переносить на другие инсталляции Scala, где разбивка учетной строки отличается, потребуется только подправить функции.

    Можно пойти еще дальше и читать разбивку учетной строки из настроек и сделать функции универсальными. Не советую этого делать, т.к. использоваться они могут довольно часто, а зачем нам лишние запросы? Поправить же функции при необходимости дело пары минут.

    Сами функции получаются простыми (создать лучше во всех компанейских базах данных, чтобы при вызове не нужно было указывать имя БД).

    Для примера возьмем следующую разбивку учетной строки: Счет - 12, УИ1 - 4, УИ2 - 6, УИ3 - 6, УИ4 - 4, УИ5 - 3, УИ6 - 6, УИ7 - 3, УИ8 - 2, УИ9 - 4. Создаем функции:


    CREATE FUNCTION dbo.Account(@AccountString nvarchar(50))
    RETURNS nvarchar(12)
    AS
    BEGIN
    RETURN rtrim(left(@AccountString, 12))
    END
    GO

    CREATE FUNCTION dbo.Dim1(@AccountString nvarchar(50))
    RETURNS nvarchar(12)
    AS
    BEGIN
    RETURN rtrim(substring(@AccountString, 13, 4))
    END
    GO

    CREATE FUNCTION dbo.Dim2(@AccountString nvarchar(50))
    RETURNS nvarchar(12)
    AS
    BEGIN
    RETURN rtrim(substring(@AccountString, 17, 6))
    END
    GO

    CREATE FUNCTION dbo.Dim3(@AccountString nvarchar(50))
    RETURNS nvarchar(12)
    AS
    BEGIN
    RETURN rtrim(substring(@AccountString, 23, 6))
    END
    GO

    CREATE FUNCTION dbo.Dim4(@AccountString nvarchar(50))
    RETURNS nvarchar(12)
    AS
    BEGIN
    RETURN rtrim(substring(@AccountString, 29, 4))
    END
    GO

    CREATE FUNCTION dbo.Dim5(@AccountString nvarchar(50))
    RETURNS nvarchar(12)
    AS
    BEGIN
    RETURN rtrim(substring(@AccountString, 33, 3))
    END
    GO

    CREATE FUNCTION dbo.Dim6(@AccountString nvarchar(50))
    RETURNS nvarchar(12)
    AS
    BEGIN
    RETURN rtrim(substring(@AccountString, 36, 6))
    END
    GO

    CREATE FUNCTION dbo.Dim7(@AccountString nvarchar(50))
    RETURNS nvarchar(12)
    AS
    BEGIN
    RETURN rtrim(substring(@AccountString, 42, 3))
    END
    GO

    CREATE FUNCTION dbo.Dim8(@AccountString nvarchar(50))
    RETURNS nvarchar(12)
    AS
    BEGIN
    RETURN rtrim(substring(@AccountString, 45, 2))
    END
    GO

    CREATE FUNCTION dbo.Dim9(@AccountString nvarchar(50))
    RETURNS nvarchar(12)
    AS
    BEGIN
    RETURN rtrim(substring(@AccountString, 47, 4))
    END
    GO

    -- Проверяем, получилось ли:

    select top 100 GL06001 AccStr,
    dbo.Account(GL06001) Acc,
    dbo.Dim1(GL06001) Dim1,
    dbo.Dim2(GL06001) Dim2,
    dbo.Dim3(GL06001) Dim3,
    dbo.Dim4(GL06001) Dim4,
    dbo.Dim5(GL06001) Dim5,
    dbo.Dim6(GL06001) Dim6,
    dbo.Dim7(GL06001) Dim7,
    dbo.Dim8(GL06001) Dim8,
    dbo.Dim9(GL06001) Dim9
    from GL06CCYY

    вторник, августа 21, 2007

    Структура БД: Главная Книга

    GL/General Ledger/ГК/Главная книга. Основной модуль, практически любая операция в конечном итоге находит свое отражение в проводках этого модуля. Вот и начнем плясать от печки. Сразу оговорюсь, что не ставлю своей целью досконально описать структуру БД, скорее это описание основных сущностей, необходимых для построения отчетов.

    По большому счету у модуля две задачи - ведение плана счетов (справочник счетов и справочник учетных измерений (УИ)) и механизм формирования проводок.

    Сначала стоит определиться с учетной строкой - это строка из 50 символов, включает в себя счет и учетные измерения. Разбивка внутри этой строки делается на этапе внедрения и потом редко меняется. Максимальное число составных частей учетной строки 9 . Подсмотреть текущую разбивку можно здесь: Системные Утилиты - Управление Деловой Информацией - Настройка Компании (System Utilities - Business Data Management - Company Setup) закладка 5.

    GL53 - Справочник счетов

    Годо-Зависимость - ДА
    Компание-Зависимость - ДА

    Поле Описание
    GL53001 Счет
    GL53002 Наименование счета
    GL53003 Тип счета.
    0 - прибылей и убытков
    1 - балансовый
    2 - статистический
    GL53005 Определяет привязку учетных измерений. Состоит из девяти символов. Каждый символ отвечает за свое УИ.
    0 - УИ не привязано
    1 - УИ должно использоваться обязательно
    2 - УИ может использоваться
    GL53006 Блокировка счета
    0 - счет можно использовать
    1 - счет заблокирован
    2 - прямой ввод для счета запрещен
    GL53009 Код книги или спецфункции. Возможные значения можно посмотреть в форме редактирования счета

    Остальные поля  редко используются при построении отчетов.

    GL03 - Справочник учетных измерений

    Годо-Зависимость - ДА
    Компание-Зависимость - ДА

    Поле Описание
    GL03001 Код учетного измерения. B - 1, C - 2, D - 3, E - 4, F - 5, G - 6, H - 7, I - 8, J - 9
    GL03002 Код учетного измерения
    GL03003 Наименование учетного измерения
    GL03004, GL03005 Описание учетного измерения

    GL06 - Проводки

    Годо-Зависимость - ДА
    Компание-Зависимость - ДА

    Можно сказать - основная таблица модуля. Именно здесь хранятся все проводки. Каждая проводка состоит из двух и более линий. Знак суммы определяет дебет это или кредит. Кроме случая красного строно - тогда минус это дебет, а плюс кредит. Строки красного сторно помечаются в поле GL06017.

    Поле Описание
    GL06001 Учетная строка
    GL06002 Номер проводки
    GL06003 Дата проводки
    GL06004 Сумма в локальной валюте
    GL06005 Текст проводки
    GL06006 Код контрагента
    GL06007 Содержимое зависит от модуля. Для КЗ и КП - это номер СЧФ
    GL06009

    Флаг периодического автораспределения (когда нужно запустить его повторно)

    GL06012 Тип проводки. По этому полю можно узнать из какого модуля создана проводка. Более подробно смотри в отдельной статье "Типы проводок".
    GL06013 Код пользователя
    GL06014 Дата ввода
    GL06016 В этом поле хранится уникальный ключ линии. Не советую пользоваться им в качестве ключа связи с другими таблицами, т.к. при некоторых операциях Скала перенумеровывает это поле.
    GL06017 Красное сторно
    0 - обычная линия
    1 - красное сторно
    GL06018 Сумма в оригинальной валюте
    GL06019 Код валюты
    GL06030

    Флаг сложного автораспределения (когда нужно запустить его повторно)

    GL06032 счет компании источника (для консолидированных компаний)
    GL06033 сумма компании источника(для консолидированных компаний)
    GL06034

    код компании источника (для консолидированных компаний)

     

    GL07 - Дневной журнал

    Годо-Зависимость - ДА
    Компание-Зависимость - ДА

    Все проводки сначала попадают в дневной журнал. При проведении операции обновления дневного журнала проводки проверяются, если данных не хватает, то выводится запрос на коррекцию проводки. Только после этого проводка попадает в таблицу GL06. Структура GL07 существенно отличается от GL06, но разобраться там нетрудно. Непосредственно в отчетах таблица дневного журнала используется нечасто.

    Другие таблицы

    Здесь приведу краткое описание некоторых таблиц:

    1. GL52 - таблица служит для хранения сальдо в разрезе счетов, периодов и учетных измерений (только до четвертого включительно). Таблица нужна для ускоренного извлечения сальдо. Для перерасчета содержимого можно запустить процедуру реконструкции сальдо. Я предпочитаю не пользоваться этой таблицей, а при необходимости считать сальдо по таблице GL06
    2. GLCB, GLCD, GLCX, GLCY - таблицы модуля Касса
    3. GL10, GL1A - параметры модуля Главная Книга
    4. GL41 - Связка консолидированных компаний по счетам

    Примеры запросов

    В запросах макросы CC и YY нужно заменить на код компании и финансовый год соответственно. Если есть

    Вывод проводки по номеру:

    select * from GL06CCYY where GL06002 = '123456'


    Расчет сальдо(кредитовое, дебетовое, свернутое) по всем счетам, начинающимся на 60 (при условии, что длинна счета 12 символов):

    select left(GL06001, 12) Account,
    sum(case when (GL06004 > 0 and GL06017 = '0')or(GL06004 < 0 and GL06017 = '1') then GL06004 else 0 end) DSaldo,
    -sum(case when (GL06004 < 0 and GL06017 = '0')or(GL06004 > 0 and GL06017 = '1') then GL06004 else 0 end) CSaldo,
    sum(GL06004) Saldo
    from GL06V106
    where GL06001 like '60%'
    group by left(GL06001, 12)


     


    Если нужно, то приведу другие примеры - спрашивайте в комментариях.

    среда, августа 15, 2007

    Структура БД ERP Scala

    При создании внешних отчетов, разработке VBA проектов очень важно ориентироваться в структуре базы данных Scala. Данная статья будет вводной частью, в дальнейшем постараюсь пройтись по основным модулям. Описание будет строится на основе версии iScala 2.2.
    При инсталляции системы создается минимум две БД. Одна системная (обычно ScaSystemDB) и база для данных компании (имя произвольное). В системной БД хранятся общие данные, определяющие системные настройки системы. Для прикладных задач нас больше интересует именно база рабочих данных. Ею и займемся.
    Каждая таблица может быть годо-зависимой и компание-зависимой. Имена таблиц формируются по шаблону MMNNCCYY, где:

    • MM - модуль (например: GL - главная книга, SC - управление запасами….)
    • NN - номер таблицы
    • CC - код компании (для компание-независимых таблиц 00)
    • YY - финансовый год (для годо-независимых таблиц 00)
    Имена полей в таблицах тоже унифицированы и составляются из префикса XXXX, копирующего первые четыре символа имени таблицы, плюс трехзначный номер по порядку.
    Пример для наглядности: таблица справочника поставщиков - PL010100:
    • PL - Purchase Ledger - Книга Закупок
    • 01 - номер таблицы
    • 01 - код компании
    • 00 - т.к. годо-независимая
    • Имена полей PL01001, PL01002, PL01003…
    Просмотреть структуру БД можно с помощью программы ScaDBConv:

    1. Выбор модуля
    2. Список таблиц выбранного модуля
    3. Свойства выбранной таблицы
    4. Списко полей, из названия, тип выбранной таблицы
    5. Информация по индексам
    Легенда значков, используемых в программе:

    На самом деле вся информация по структуре БД хранится в таблице SCA_TAB_COLUMNS в компанейской базе, если у вас нет доступа к ScaDBConv, то можно считать ее прямо оттуда.

    UPDATE 28.11.2009: Добавлено небольшое веб-приложение, показывающее структуру базы данных iScala. Сделано на основе версии 2.3 SR2.

    четверг, августа 09, 2007

    Как удалить профиль пользователя

    Есть в iScala 2.2 SR1 дурная ошибка - меню распахивается на весть экран, при запуске любой команды рабочая область не видна. Возникает она довольно редко, лечится обычно переключением несколько раз разрешения монитора и запуска Scala на этих разрешениях (может есть более простой способ лечения?). Но бывает это не помогает, переключаешь-переключаешь, а результата нет. Вот после одного такого раза я написал инструкцию как удалять профиль. С тех пор на эту ошибку ни разу не натыкался, может исправили? Очень рад, если так, а инструкция все-таки на всякий случай, вот(да в конце-концов мало ли для какой цели потребуется удалить профиль):
    1. Выйти из Скалы. Все последующие действия, за исключением скрипта, нужно производить непосредственно на компьютере пользователя, если используется терминальный доступ, то на том терминале, где работает пользователь
    2. Запустить RegEdit. Путь: HKEY_LOCAL_MACHINE\SOFTWARE\Scala Business Solutions NV\Windows Deployment Server\1.0\Paths
    3. Берем из ключика UserProfileCache путь и открываем по этому пути Проводник:
    4. Открываем в notepad файл DirectoryMap.xml:
      <?xml version="1.0" encoding="UTF-16"?>
      <DirectoryMap Version="1">
          <Mapping UserName="RUS" Directory="00000313"/>
          <Mapping UserName="SCALA" Directory="00001661"/>
          <Mapping UserName="ADMIN" Directory="00004CCD"/>
      </DirectoryMap>
    5. Находим строку, отвечающую за нужного пользователя, удаляем папку, указанную в ключе Directory. Например, если нам нужно удалить профиль для пользователя RUS, то нужно удалить папку 00000313 и удалить строку, чтобы получилось следующее:
      <?xml version="1.0" encoding="UTF-16"?>
      <DirectoryMap Version="1">
          <Mapping UserName="SCALA" Directory="00001661"/>
          <Mapping UserName="ADMIN" Directory="00004CCD"/>
      </DirectoryMap>
    6. Находим нужного пользователя в таблице ScaUsers системной базы данных Скалы, запоминаем значение поля UserID
    7. Выполняем скрипт в системной базе данных Скалы:
      DELETE pd
      FROM ScaUserProfileEntryDesc pd
      INNER JOIN
      ScaUserProfileEntries p On p.EntryID = pd.EntryID
      WHERE p.UserID = 233 -- !!! Заменить на реальный UserID
      DELETE FROM ScaUserProfileEntries WHERE UserID = 233 -- !!! Заменить на реальный UserID
    Не забывайте, что удаляя профиль, вы удаляете все личные настройки данного пользователя: расположение и размер окон, настроенные кнопочки и т.д.

    четверг, августа 02, 2007

    TTX на основе отчета

    Все встроенные отчеты iScala на Crystal Reports используют в качестве источника данных Field Definition File - это текстовый файл, в котором описана структура данных, передаваемых отчету. Данный файл нужен только при разработке отчета, при рабочем формировании он не используется. Расширение у таких файлов TTX, поэтому часто их и называют TTX файлы.

    Проблемы возникают когда вы решаете изменить уже существующий отчет. По закону подлости оригинальных TTX файлов не находится. Беда это небольшая, ведь в самом отчете есть вся нужная информация, нужно только ее оттуда достать.

    Для восстановления TTX можно воспользоваться скриптом, написанным Sergey Mikhno. Скачать его можно здесь.

    Запускается скрипт из командной строки: createttx.bat МойОтчет.rpt

    В результате работы скрипта будут сформированы все TTX и ссылки внутри отчета будут исправлены, т.е. будут указывать на вновь сформированные файлы. Советую делать все эти операции над копией, а не над оригинальным отчетом.

    среда, июля 25, 2007

    Корреспонденция счетов

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

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

    Можно ли обойти это? Например, поможет генератор отчетов RGW, один из режимов работы которого позволяет строить отчеты по корреспонденции. Как это делается - создается отдельная таблица RG_MEMORY. В эту таблицу RGW в полуавтоматическом режиме разносит проводки, пытаясь привести все к двухстрочному виду, для сложных случаев есть ручной режим разноски. После заполнения промежуточной таблицы генератор строит по ней отчет.

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

    четверг, июля 19, 2007

    UDDB: Дополнительные поля покупателя

    Продолжаю тему UDDB. Потренируемся на покупателях. Предположим в карточке покупателя вы хотите иметь еще несколько полей, а все доступные поля уже использованы. Будем добавлять их средствами UDDB. Для простоты предположим, что нам нужно два дополнительных поля "Имя руководителя/Boss Name" и "E-mail". Весь процесс и скриншоты сделаны на версии iScala 2.2 SR2.

    Создаем таблицу для дополнительных полей: Scala Administration Console -> User Defined Database -> User Defined Tables -> New User Defined Table…

    Выбираем, что новая таблица связана отношением один к одному со справочником покупателей SL01

    Создаем два новых поля (одно поле уже создано для связи со справочником)

    По окончании работы визарда во всех компаниях будет создана новая таблица.

    Теперь нужно активировать все это в каждой компании, где это требуется. Этот процесс в Скале на мой взгляд сделан неоправданно запутанным, так что по шагам:

    1. Определяем диапазон покупателей, для которых хотим активировать ввод дополнительных полей - в нашем случае это все покупатели. System Utilities -> Extra Data -> Business Data Delimitation -> Enter/Adjust Common Range
    2. Создаем новую цепочку System Utilities -> Extra Data -> UDDB Chain Codes
    3. Привязываем цепочку к UDDB таблице System Utilities -> Extra Data -> Enter/Adjust Chains
    4. Сводим все вместе System Utilities -> Extra Data -> Extra Data Definitions -> Enter Extra Data Definition

    Если нигде не ошиблись, то должно работать. Идем Sales Ledger -> Customer File -> Enter/Adjust Customer. Выбираем любого покупателя, после загрузки жмем Escape и видим новую форму

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

    Функциональность достаточно удобная. Поля можно привязывать выборочно, т.е. одной группе покупателей одни, одной другие, а можно и несколько наборов. Можно сделать связь один ко многим. Есть и свои минусы: запутанная настройка, дополнительная форма не встраивается, а появляется после закрытия основной.

    четверг, июля 12, 2007

    UDDB: Несвязанные таблицы

    User Defined Database (UDDB) - Таблицы определенные пользователем. Возможность iScala незаслуженно редко используемая в реальной жизни.

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

    Плюсы:

    • Scala будет знать об этой таблице, что позволит ей, например, добавить содержимое таблицы в плоский бекап или при копировании компании создать в новой компании эту таблицу
    • Если компания годо- или компание-зависимая, то Scala сама будет следить за наличием таблиц при создании нового года или компании
    • Появится простейший интерфейс для редактирования
    • Новая таблица будет документирована, можно всегда глянуть и увидеть весь набор дополнительных таблиц, а не мучительно вспоминать, что же еще ты забыл создать в новой компании

    Минусы:

    • Лишнее поле GUID (не думаю, что это страшно)

    Мое мнение - по возможности нужно все дополнительные таблицы оформлять как UDDB.

    Как создать несвязанную таблицу? Все просто:

    1. Запускаем iScala Administration Console
    2. Базы Данных определенные пользователями -> Таблицы Определенные Пользователями -> Новые таблицы Пользователей
    3. Появляется визард, понятный без особых описаний

    Интерфейс для редактирования в стандартном меню: Системные Утилиты -> Дополнительные Данные -> UDDB -> Ввод/Корректировка Несвязанных Таблиц

    пятница, июля 06, 2007

    Дополнительные функций для CR

    Crystal Reports имеет встроенный язык(даже два), который позволяет писать дополнительные функции. Эти функции можно выделять в общие и использовать в разных отчетах. Вот, например, простая функция печати даты вида "31 декабря 2007 г.", работа которой не зависит от региональных и языковых настроек компьютера пользователя:

    Function (DateVar Dt)
      numberVar dd;
      numberVar mm;
      numberVar yy;
      stringVar sm;
      dd := Day(Dt);
      mm := Month(Dt);
      yy := Year(Dt);
      stringVar array MonthNames := ["Января", "Февраля", "Марта", "Апреля", "Мая", "Июня", "Июля", "Августа", "Сентября", "Октября", "Ноября", "Декабря"];
      CStr(dd, 0) & " " & MonthNames[mm] & " " & CStr(yy, 0, "") & " г."

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

    Спецификация по созданию таких библиотек можно найти на сайте CR.

    В составе iScala идет такая библиотека. Более подробно смотри раздел помощи "Special Functions for Crystal Reports".

    В своей работе я часто пользуюсь одной такой библиотекой. Изначально она была написана Alexey Vishnyakov из SCALA CIS. С тех пор разными людьми в нее вносились изменения и добавлялись новые возможности.

    Список функций библиотеки:

    • avvScaCRGetStringField(SqlString As String) As String - выполняет произвольный SQL запрос SqlString и возвращает значение текстового поля из БД. В запросе можно использовать макросы <CC> и <YY> - они будут заменены на код компании и финансовый год соответственно.
    • avvScaCRGetNumericField(SqlString As String) As Double - тоже, но для числового поля
    • avvScaCRGetDateField(SqlString As String) As Date - тоже, но для поля типа дата
    • avvScaCRNumStr(N As Currency, rub As Integer) As String - представление числа прописью.
      При втором аргументе функции равном:
      0 - вывод только числа прописью,
      1 - дополнительно вывод "рублей" и "копеек"
      2 - дополнительно вывод у.е. и сотых у.е.
      3 - дополнительно вывод "долларов" и "центов"
      4 - дополнительно вывод "ЕВРО" и "центов"
      5 - дополнительно вывод "ГРИВНЫ" и "копейки" (на украинском языке)
    • avvScaCRScaNumToNumber(strNum As String) As Double - конвертация текстовой строки в число
    • avvScaCRScaFormatNumber(Num As Double, ThousandSeparator As String, DecimalSeparator As String, DecimalPlaces As Integer) As String - форматирование числа
    • avvScaCRScaNumberToStr(Num As Double) As String - конвертация числа в строку в соответствии с настройками компании
    • avvScaCRScaShortDateToDate(StrDate As String) As Date - конвертация текстовой строки типа в дату

    К сожалению функции, работающие с БД, не всегда правильно работают с несколькими сессиями. Я уже описывал эту проблему тут.

    Саму библиотеку и ее исходный код можно скачать здесь.

    Для установки нужно зарегистрировать DLL на всех компьютерах, где будут использоваться такие отчеты командой: regsvr32 CRUFLavv.dll

    Должно появиться сообщение "DllRegisterServer в CRUFLavv.dll завершено успешно."

    После этого новые в списке функций появятся новые пункты, путь к ним Functions/Additional Functions/Visual Basic UFLs (u2lcom.dll):

    Можно пользоваться.

    воскресенье, июля 01, 2007

    Запуск внешней программы из меню (Часть 2)

    Итак, второй способ запуска, правильно работающий с несколькими одновременно запущенными копиями Scala. Он немного сложнее и требует наличия вспомогательной DLL. Эту библиотеку нужно зарегистрировать на всех компьютерах.

    Цель вспомогательной DLL - прикинуться скальской библиотекой, забрать у Скалы все нужные данные и запустить нашу программу, передав в параметрах командной строки собранную информацию. Все это она и делает. Библиотека реально используется у многих клиентов с версиями iScala 2.2 CR, iScala 2.2 SR1, iScala 2.2 SR2, iScala 2.3

    Попробуем все это проверить:

    1. Скачиваем этот архив. В нем DLL, исходные коды DLL, и тестовое приложение.
    2. Выкладываем ExtLauncher.dll (обычно это какой-нибудь общий каталог на сервере, доступный для пользователей Скалы)
    3. Регистрируем DLL командой:
      regsvr32 ExtLauncher.dll
    4. Заводим в меню новую команду
      название действия - ExtLauncher.Launcher
      параметры - путь к программе в двойных кавычках
    5. Убеждаемся, что все работает

    пятница, июня 29, 2007

    Запуск внешней программы из меню (Часть 1)

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

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

    Второй способ - подключаем программу в меню, выбирая тип "Выполняемый модуль Windows"/"Windows executable" и указываем путь к программе. Все у нас теперь запускается, осталось определить нужные параметры. Если эту программу пишете вы сами, то есть способ определить все что нужно. Вот как это будет выглядеть на примере Visual Basic 6:

    1. Создаем новый проект
    2. В References добавляем ссылку на SfwIII
       
    3. Кидаем на форму черыре Label, обзываем их llCompanyCode, llScalaYear, llScalaDate, llConnectionString
    4. Добавляем следующий код
      Private Sub Form_Load()
      llCompanyCode.Caption = SfwIII.ActiveProcess.UserContext.CompanyCode
      llScalaYear.Caption = Right(CStr(SfwIII.ActiveProcess.UserContext.FinYear), 2)
      llScalaDate.Caption = SfwIII.ActiveProcess.ScalaDateStr
      llConnectionString.Caption = SfwIII.ActiveProcess.UserContext.GetConnectionString(2)
      End Sub
    5. Настраиваем новый пунт меню
       
    6. Запускаем
       

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

    Исходник примера можно взять здесь.

    Не обошлось у этого способа без недостатков. Неприятности начинаются когда пользователь запускает несколько копий Скалы. В этом случае программа всегда будет получать параметры из программы запущенной первой. Правда, если открыть второе окно с помощью пункта меню "Изменить Компанию/Год" с галочкой "Запуск новой сессии", то все будет работать нормально.

    О способе запуска, правильно определяющем сессии, расскажу в следующий раз.

    среда, июня 27, 2007

    Let’s go

    Мысль создать блог на тему Скалы пришла неожиданно и еще удивительней, что я решил попробовать это сделать. Этот первый пост, своеобразная декларация намерений.

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

    Автор. Дмитрий Пестов, работаю консультантом, чаще всего имею дело с продуктами Epicor iScala 2.x. Занимаюсь в основном техническими вопросами. Если будет интерес, то в будущем постараюсь подбить еще кого-нибудь из коллег на написание материалов.

    Цель. Систематизировать для себя знания. Посмотреть интересна ли эта тема для кого-нибудь кроме меня. Обмен опытом. Поиск клиентов.