Многие, вероятно сталкивались с такой задачей, как построение в памяти быстрого индекса и поиска в нем по нескольким реквизитам. В платформе 8.х худо-бедно этот вопрос решается на уровне запросов и данных, а в 7.7 он "красиво" не решается никак, и вобще не решается для операций с данными которые динамически находятся в памяти.
Попытавшись решать его когда-то на уровне слияния уникальных строк вроде: ЗначениеВСтрокуВнутр(..), я столкнулся с тем, что построение индекса для нескольких параметров растет катастрофически, длина строки в памяти для 1С ограничена, а при работе со списками где присутствует от 1000 строк и более, этот способ совсем плох.
Немного почитав документации и собрав в кучу остатки знаний по разработке в среде Delphi я наваял простенькую библиотеку, которую можно вызывать как из среды 7.7 так и 8.х. Скорость ее работы зависит от длины параметра, но достаточно велика, что отладчик иногда считает что время ее выполнения близко к нулю ;)
Регистрация библиотеки стандартная:
regsvr32 AddIn.dll
После этого в коде своей конфигурации вы можете производить с ней манипуляции обратившись к экземпляру объекта
"AddIn.AddInHasher"
Поскольку я практически применял ее только в разработке конфигураций на базе 1С версии 7.7, предлагаю краткий пример ее работы. Метод у внешней компоненты один
ВзятьХеш(_Параметр)
где: _Параметр - строка любой длины, которую вы сможете передать в вызываемый метод. Возвращает функция строку размером 20 символов. Внимание: на первых порах частой ошибкой сравнения результатов вычисления хеш-функции было то, что во входных параметрах оставались незначащие пробелы по краям (например при вводе из форм диалогов типа "Строка"), будьте внимательны к тому какие данные вы даете функции, т.к. даже незначительное различие входных строк, вызывает разный результат расчета.
Если в конфигурации объявлена переменная, которая всегда проинициализирована как объект этой библиотеки, то в табло 7.7 вы можете попробовать выполнить подобный пример:
_глпХешер.ВзятьХеш("qwe") = dtgCJGEfyRml1U8P+fuk
СтрДлина(_глпХешер.ВзятьХеш("qwe")) = 20
Я намеренно сократил выводимое значение хеш-функции до 20 символов на низком уровне, это немного снижает вероятность неповторяемости оригинального алгоритма (даже 10^-20 степени это вероятность космического масштаба ;), однако снимает необходимость усечения итоговой строки для применения в качестве индекса отборов в журналах документов, индекс которых, для реквизитов строкового типа, доблестные программисты 1С, вычисляют только у 20 первых символов - как бы вы не старались. Если кому интересно об этом приеме сообщу ниже.
Итак, пример кода для запуска в собственных разработках:
//Пример дакларации глобальной переменной
Перем _глпХешер Экспорт;
//Инициализация переменной для использования
_глпХешер = СоздатьОбъект("AddIn.AddInHasher");
//Рассчитывает кумулятивный хеш от серии до пяти входных параметров для запроса (например) реляций колонок из ТЗ
Функция _глПолучитьРасчетХешаОтПараметров(_Пар1, _Пар2="", _Пар3="", _Пар4="", _Пар5="") Экспорт
Возврат _глпХешер.ВзятьХеш(ЗначениеВСтрокуВнутр(_Пар1) +
?(_Пар2="", "", ЗначениеВСтрокуВнутр(_Пар2)) +
?(_Пар3="", "", ЗначениеВСтрокуВнутр(_Пар3)) +
?(_Пар4="", "", ЗначениеВСтрокуВнутр(_Пар4)) +
?(_Пар5="", "", ЗначениеВСтрокуВнутр(_Пар5)));
КонецФункции
Примеров применения на самом деле очень много, и это видимо повод для отдельной статьи. Но раз обещал, подробнее расскажу про отборы в журналах документов:
Многие "избалованные" программисты на платформе 8.х )) сейчас не очень озадачены тем, что бы в журнале документов иметь возможность отбирать список журнала по нескольким реквизитам. В 7.7 стандартными средствами эта задача не решается вообще, а ковырять bkend.dll для того что бы подставлять запросы к SQL или заниматься по советам некоторых любителей ковыряниями в самих индексах и отображениях внутри SQL для разрабатываемой базы, я счел крайне неприемлемыми. Итак: "как это работает" с использованием стандартных средств и приведенной DLL?
Приведу пример в форме описания методологии:
Предположим, нам необходимо сделать перекрестный отбор по комбинациям полей "МОЛ" и "Склад" в документах "Приходная накладная", "Перемещение ТМЦ" и "Реализация ТМЦ".
1. Вводим в каждый из этих документов строковый реквизит размером 20 символов (больше не имеет смысла), назовем ее "_ршОтборМОЛСклад".
2. Для каждого документа в модуле "ПриЗаписи" вычисляем значение хеш-функции от реквизитов "МОЛ" и "Склад". Пример:
_ршОтборМОЛСкладу = _глПолучитьРасчетХешаОтПараметров(МОЛ, Склад);
Для уже наполненной базы придется написать временную обработку, которая заполнит указанным хешем требуемые документы.
4. В разделе "Журналы" вводим графу отбора "_гоОтборМОЛСклад", от поля "_ршОтборМОЛСклад" в которую включаем строковые реквизиты шапки названных документов.
3. Создаем общий журнал с интерфейсом, где пользователь в форме журнала, выбирает произвольные значения "МОЛ" и "Склад" и по выбору каждого из реквизитов, вызываем модуль, который выполняет примерно следующее:
_пХешМОЛСклад = _глПолучитьРасчетХешаОтПараметров(МОЛ, Склад);
УстановитьОтбор("_гоОтборМОЛСклад", _пХешМОЛСклад);
Собственно все - после этого вы обладаете мощным инструментом отбора документов в журнале не менее функционального чем в средствах 8.х.
Скажу, что это частный, наиболее простой пример применения. Я на самом деле использую этот инструмент для отбора по нескольким измерениям в справочниках, для отбора по виду документа в регистре (операция Вид() крайне медлительная для запрососв в 10-100 тыс. строк). При построении собственных систем учета заработной платы и многих других примерениях, которые стандартными средствами неразрешимы или требуют в несколько раз больше вычислительных ресурсов, если применять встроенный язык и проводить сравнения операцией логичского "И" в условиях.
Надеюсь, я был понятен, если есть вопросы, с удовольствием отвечу. Желаю удачи.