Недавно озадачился получением CRC кода для строк табличной части и вот что из этого получилось. Работы по настоящей тематике проходили в несколько этапов.
Этап 1
Изучение теоретических основ расчета CRC. На этом этапепомогли статьи » Циклический избыточный код« и «Элементарное руководство
по CRCалгоритмам обнаружения ошибок»
Этап 2
Знакомство с NativeAPI для 1С8. Отличная, доходчивая и (главное) дополненая примерами статья «ВК NativeAPI на Delphi и FreePascal«
Этап 3
Оставим теорию и переходим к практике. На любимом Delphi была напишем и скомпилируем dll, которая экспортирует единственную функцию «РасчитатьCRC32». Ей передается единственный строковый параметр, а на выходе получается строка в виде hex.
В модуле проекта объявляем класс:
TCRC32Class = class(TV8UserObject)
public
function crc32Func(RetValue: PV8Variant; Params: PV8ParamArray; const ParamCount: integer; var v8:TV8AddInDefBase): boolean;
end;
и его реализацию:
function TCRC32Class.crc32Func(RetValue: PV8Variant;
Params: PV8ParamArray;
const ParamCount: integer;
var v8:TV8AddInDefBase): boolean;
var
p: WideString;
res: string;
begin
try
p := V8AsWString(@Params[1]);
res := IntToHex(CRC32String(p),0);
V8SetWString(RetValue, res);
result := True;
except
on E : Exception do begin
res:='['+E.ClassName+'] '+E.Message;
V8SetWString(RetValue, res);
result := False;
end;
end;
end;
также в части инициализации библиотеки пишем вот такой код:
with ClassRegList.RegisterClass(TCRC32Class, 'ExecExtention', 'TCRC32Class') do
begin
AddFunc('crc32Func', 'РасчитатьCRC32', @TCRC32Class.crc32Func, 1);
end;
Функция CRC32String реализована в модуле ucrc32.pas, а класс TV8UserObject описан и реализован в модуле v8napi.pas (см. ссылку во втором этапе). Об окончании этого этапа работ сигнализирует файл p1c8crc.dll.
Этап 4
Теперь осталось подключить внешнюю компоненту к конфигурации 1С8.2 и использовать ее. Для этого создадим общий модуль «ОбщийМодульCRC32». В нем напишем вот такой код:
Функция ИнициализироватьКомпонентуCRC32() Экспорт
Попытка
ПодключитьВнешнююКомпоненту("ОбщийМакет.p1c8crc", "CRC32Lib", AddInType.Native);
ОбъектВК = Новый("AddIn.CRC32Lib.ExecExtention");
Исключение
Сообщить("Ошибка создания объекта внешней компоненты AddIn.CRC32Lib.ExecExtention");
Возврат Ложь;
КонецПопытки;
Адрес = ПоместитьВоВременноеХранилище(ОбъектВК, Новый УникальныйИдентификатор);
ПараметрыСеанса.нсиКомпонентаCRC32 = Адрес;
Возврат Истина;
КонецФункции
Функция ПолучитьКомпонентуCRC32() Экспорт
Возврат ПолучитьИзВременногоХранилища(ПараметрыСеанса.нсиКомпонентаCRC32);
КонецФункции
В модуле сеанса проинициализируем компоненту. Для того чтобы вызвать внешнюю компоненту и проверить ее создадим обработку с табличной частью «ТЧ» (реквизиты: наименование, код и crc32) и команду «РасчитатьCRC». Код получился следующий:
&НаСервере
Процедура РасчитатьCRCСерверная()
ВК = ОбщийМодульCRC32.ПолучитьКомпонентуCRC32();
Для Каждого Стр Из Объект.ТЧ Цикл
врСтрока = Стр.Наименование+";"+Стр.Код+";";
Стр.CRC32 = ВК.РасчитатьCRC32(врСтрока);
КонецЦикла;
КонецПроцедуры
&НаКлиенте
Процедура РасчитатьCRC(Команда)
РасчитатьCRCСерверная();
КонецПроцедуры
P.S.
Чуть не забыл. В общих макетах нужно создать макет с двоичными данными и именем «p1c8crc». В нее загрузить полученный на этапе 3 файл p1c8crc.dll.
Пишется то «Рассчитать» 😉 Единственный метод, и тот с ошибкой написан.