Книга знаний

1С:Предприятие / Приемы программирования / Внешние компоненты

Написание внешних компонент для 1С (Delphi)

В статье описана разработка внешних компонент для 1С:Предприятие в среде программирования Delphi. Я постарался создать удобный для понимания и функциональный шаблон внешней компоненты, который можно было бы использовать без предварительной подготовки, зная, в общих чертах, программирование в Delphi. Пример внешней компоненты для скачивания приведен в конце статьи.Автор статьи: romix | Редакторы: pectopatop,
Последняя редакция №4 от 06.08.06 | История
URL: http://kb.mista.ru/article.php?id=319

Ключевые слова: Внешняя компонента, DLL, Delphi


Насколько мне известно, многие 1С-ники хотели бы изучить написание внешних компонент, чтобы поднять свое магическое искусство 1С на качественно иную ступень.

Что этому может помешать? Во-первых, известный синдром компонентофобии (который исторически берет свое начало от криво написанных внешних компонент). Во-вторых –синдром  клинически запутанного кода. OLE-программирование – это не самая простая штука, и, как говорится, «не всякая птица долетит до середины Днепра» (особенно, если эта «птица» – программист 1С).

Я предлагаю вашему вниманию шаблон внешней компоненты, который, как я надеюсь, достаточно прост для понимания (я постарался его значительно упростить по сравнению с типовым примером из «Технологии создания внешних компонент») и стабилен (везде, где это возможно, я использую обработку исключительных ситуаций).

Сборка проекта



Для компиляции примера потребуется среда разработки Delphi 6 или 7.

Файл проекта - TestVK.dpr.
Откройте этот файл (например, двойным щелчком мыши из Проводника).
Нажмите сочетание клавиш Ctrl-F9 (или пункт меню Project-Compile). Если все прошло нормально, в этой же папке образуется готовая внешняя компонента  TestVK.dll (для проверки, а все ли хорошо, ее можно удалить, и получить готовую TestVK.dll еще раз).

При компиляции должна быть закрыта программа 1С в режиме Предприятие – иначе файл DLL будет заблокирован системой, и Delphi напишут пугающее сообщение: [Fatal Error] Could not create output file 'TestVK.dll'

Проверка работоспособности DLL



В комплект примера входит тестовая конфигурация 1С:Предприятие 7.7.

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

Переименование DLL


Первое, что я делаю при создании новой внешней компоненты – переименовываю уже существующий образец.

Переименуйте TestVK.dpr так, как вы хотите (например, MyVK.dpr).

Произведите замену всех вхождений подстроки TestVK в файлах проекта на нужное вам имя внешней компоненты.

Подсказка: чтобы открыть другие модули проекта, используйте пункт меню View-Units…

Программный код 1С, разумеется, также нужно не забыть изменить так, чтобы заменить все подстроки «TestVK».

Важно: замените значение CLSID внешней компоненты, чтобы новая DLL, с точки зрения Windows, стала действительно новой.
     CLSID_AddInObject : TGUID = '{CE4FB6DB-636C-4824-86C4-DCE02135FE5A}';


Чтобы сгенерировать новый CLSID, нажмите сочетание клавиш Ctrl-Shift-G.

Попробуйте скомпилировать новый проект – 1С должна «увидеть» вашу новую внешнюю компоненту, которая создана на основе другой ВК, но содержит полный набор ее свойств и методов.

Что такое свойства и методы?


Новички могут задаться вопросом, а что такое свойства и что такое методы?
В коде 1С свойства выглядят как, своего рода, «переменные», объекта, доступные через точку, например
    vk.Заголовок="Внешняя компоннета";

Здесь объект – имеет имя vk (посмотрите, как он объявляется и инициализируется в глобальном модуле 1С).. Этот объект поддерживает свойства и методы.

В этом коде я установил свойству "Заголовок" текстовое значение (посмотрите, как будет работать пример, если установить этому свойству другое значение заголовка, например, «Здесь был romix», или не устанавливать его вовсе).

Метод объекта – это, своего рода, «функция» объекта, доступная «через точку».
    vk.ВсплывающаяПодсказка("Проверка всплываюшего сообщения", 3000);

Метод может иметь параметры. В данном примере, параметры – это «Проверка всплывающего сообщения» и 3000 – попробуйте установить в коде 1С что-нибудь другое и нажать кнопку «Сообщение» в тестовом отчете.

Изменение списка свойств и методов ВК


В модуле AddinObj.pas за количество свойств отвечают участки кода, которые я пометил (*2*), (*5*), (*6*), (*8*), (*11*) а за количество методов - (*3*), (*7*), (*9*), (*10*), (*12*).

Я завел в шаблон по 5 свойств и методов, но что нужно сделать, чтобы их стало 6, например, в приведенном ниже фрагменте кода, - я надеюсь, понятно без объяснений.
            prop1: vk_object.prop1(m_get_value);
            prop2: vk_object.prop2(m_get_value);
            prop3: vk_object.prop3(m_get_value);
            prop4: vk_object.prop4(m_get_value);
            prop5: vk_object.prop5(m_get_value);


Вы можете завести свойства и методы «с запасом» - лишние заготовки не повредят (их можно будет оставить пустыми).

Программирование функциональности свойств


Откройте (через меню View – Units…) модуль vk_object.pas

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

  /////////////////////////////////////////////////////////////////////
  function T_vk_object.prop1(mode: TMode): String;
  begin
    case mode of
      m_rus_name: Result:='Пиктограмма';
      m_eng_name: Result:='IconType';
      m_get_value: g_Value:=g_IconType;
      m_set_value: g_IconType:=g_Value;
    end;//case
  end;


Что я здесь делаю?

  • m_rus_name – устанавливаю русское имя свойства (в данном случае, свойство называется Пиктограмма). В коде 1С я пишу что-то вроде

    vk.Пиктограмма=32;

    Вот здесь 1С и узнает, что свойство называется именно Пиктограмма (а не как-то иначе). Попробуйте переименовать свойство (например, в Псиграмма), и посмотрите, что получится.

  • m_eng_name - англоязычный синоним - 'IconType' – я устанавливаю строкой ниже.

  • m_get_value –1С получает значение переменной, в данном случае, g_IconType.
    Что это за переменная? А это та переменная (точнее, свойство класса), где я решил запоминать идентификатор своей пиктограммы.

  • m_set_value – 1С устанавливает значение свойства.
    Наличие этой строки позволяет изменять числовое значение моей пиктограммы из кода 1С. Попробуйте выставлять из кода 1С различные значения пиктограммы (в комментариях примера я описал, какие значения возможны), и смотреть, что получится.
  • Программирование функциональности методов


    Для методов код похожий:

      /////////////////////////////////////////////////////////////////////
      function T_vk_object.meth1(mode: TMode): String;
      var s: String;
      var ms: Integer;
      begin
        case mode of
          m_rus_name: Result:='ВсплывающаяПодсказка';
          m_eng_name: Result:='BalloonTooltip';
          m_n_params: g_NParams:=2; //Количество параметров функции
          m_execute: begin
            //Извлекаем параметры функции, переданные из 1С
            s:=GetParamAsString(0);//сообщение
            ms:=GetParamAsInteger(1);//задержка в мс
            //Показываем сообщение в трее
            sleep_icon(s, ms);
          end;
        end;//case
      end;
    

    Этот абзац можно воспроизвести несколько раз (что и сделано в примере), заменив meth1 на meth2, meth3 и т.д.

    Приведенные ниже строчки устанавливают русское и английское имя метода.
          m_rus_name: Result:='ВсплывающаяПодсказка';
          m_eng_name: Result:='BalloonTooltip';


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

    В строчке
        m_n_params: g_NParams:=2; //Количество параметров функции

    я устанавливаю количество параметров метода. Попробуйте изменять это количество (например, установить значение 3) и посмотреть, что получится.

    Блок
          m_execute: begin
    //…
          end;
    

    реализует собственно функциональность метода (показывает всплывающее сообщение в трее).

    Подробнее код я опишу ниже – но сначала полезно потренироваться со вставкой в него отладочной печати (именно так я исследую код).

    Отладочная печать


    Вы можете в качестве теста вписать в функциональность метода что-то свое, например,

    MessageBox(0, ‘Превед’, ‘Медвед’, 0);

    Этот вызов покажет стандартное окно предупреждения с кнопкой ОК.

    Получение параметров функции
    В своей функции я завел две переменные для хранения параметров:
      var s: String;
      var ms: Integer;


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

    Сейчас мы их заполним значениями, полученными из 1С.

            s:=GetParamAsString(0);//сообщение
            ms:=GetParamAsInteger(1);//задержка в мс
    

    Параметры нумеруются, начиная с 0 (давняя традиция программистов на языке С).

    Чем отличаются AsString и AsInteger, надеюсь, понятно.

    Этот код можно было бы написать и так:
            s:= GetNParam(0);//сообщение
            ms:= GetNParam(1);//задержка в мс
    

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

    Отладочная печать параметров


    При отладке полученные из 1С значения полезно выводить на экран. Но как это сделать?
    Я обычно использую следующий прием:

    Чтобы показать строковые переменные, я пишу так:

    MessageBox(0, pchar(s), 'Отладка - s', 0);


    А числовые значения я отображаю примерно так:

    MessageBox(0, pchar(IntToStr(ms)), 'Отладка - ms', 0);


    Функциональность методов



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

    Функция sleep_icon(s, ms); определена в коде примера, и показывает сообщение, используя функции Windows API (Application Programming Interface).

    Узнавать, как работают те или иные функции API, можно в поисковых машинах или в сборниках Delphi FAQ, которые в изобилии выложены в сети Интернет.

    Хороший сборник рецептов и примеров – диск MSDN от Microsoft.


    Пример для скачивания


    http://x-romix.narod.ru/TestVK.rar
    (Скачивать левой кнопкой мыши, 80 килобайт).

    Описание | Рубрикатор | Поиск | ТелепатБот | Захваченные статьи | Установки | Форум
    © Станислав Митичкин (Волшебник), 2005-2025 | Mista.ru

    Яндекс.Метрика