Tuesday, December 11, 2007

Нетипичное использование компоненты УРБД в системе 1С:Предприятие 7.7

http://www.kb.mista.ru/article.php?id=45

При организации обмена между двумя информационными базами (не обязательно 1С:Предприятие) возникают две сложности: как узнать, а какие же объекты были изменены с момента последней отгрузки информации (чтобы выгружать не все данные, а только необходимое), и как отследить доставку пакетов обмена (если пропал один или два пакета, то это не должно приводить к глобальному сбою: пакеты, по которым не пришло подтверждение доставки, должны быть просто и прозрачно отправлены при следующем сеансе обмена). Автор статьи: romix | Редакторы: Волшебник
Последняя редакция №9 от 14.05.07 | История
URL: http://kb.mista.ru/article.php?id=45


Ключевые слова: УРБД, распределенная база, регистрация изменений, 1SUPDTS, TYPEID, OBJID


Давайте рассмотрим, как технология надежной доставки реализована в компоненте УРБД 1С:Предприятие 7.7 «изнутри» (на уровне исходных таблиц информационной базы). Это особенно интересно, если мы хотим реализовать взаимодействие с другими системами (не обязательно 1С), не отказываясь, в то же время, от удобных средств, предоставляемых программисту компонентой УРБД.

Установка и настройка распределенной базы УРБД «с нуля» описана в статье Работа с компонентой УРБД в 1С 7.7 (пошаговая инструкция+скрипт).

Для просмотра и правки файлов DBF рекомендую программу DBFNavigator от Алексея Долгачева.

Ниже приведены результаты моих собственных изысканий (поправки и дополнения приветствуются).

1SUPDTS.DBF

Таблица хранит записи об измененных объектах 1С:Предприятие, которые подлежат отправке получателям.

DBSIGN (тип: Строка 3) – Код базы УРБД, как он задан в окне настроек в меню Администрирование - Распределенная ИБ – Управление. Это код базы-адресата, куда должен быть отправлен объект (например, пользовательский документ или элемент справочника). Если есть несколько баз-получателей, то в таблице будет несколько записей (строчек) для одного и того же объекта (например, измененного элемента справочника товаров).


TYPEID (тип: Строка 4) – Идентификатор типа объекта 1С, например, документа или справочника. Значение хранится в 36-й системе счисления.
OBJID (тип: Строка 9) – Внутренний числовой идентификатор объекта (например, пользовательского документа или элемента справочника), как он представлен в методе ЗначениеВСтрокуВнутр(). Необходимы ведущие пробелы.


DELETED (тип: Строка 1) – Признак непосредственного (не пометка на удаление!) удаления объекта, 1=да или 0=нет.
DWNLDID (тип: Строка 9) – Идентификатор пакета выгрузки, как в 1SDWNLDS.DBF (см. ниже).

Расшифровка записей об измененных объектах


Основная проблема при расшифровке информации из этой таблицы – как средствами 1С получить ссылку на объект (например, элемент справочника), если известен его TYPEID и OBJID.

Во-первых, преобразование значения TYPEID в/из 36-й системы счисления в десятичную можно произвести при помощи (недокументированных) функций _StrToId() и (обратное преобразование) - _IdToStr().


Во-вторых, пара TYPEID (в десятичной системе) и OBJID фигурирует в методах ЗначениеИзСтрокиВнутр() и ЗначениеВСтрокуВнутр(). Вы можете попытаться выгружать существующие объекты во внутреннее текстовое представление, и смотреть, какое у них будет значение этих параметров.
В-третьих, для разбора и формирования этих строк удобно применять методы работы со списками значений – ВстрокуСРазделителями() и ИзСтрокиСРазделителями().

Пример получения измененных объектов

Ниже приведен пример чтения 1SUPDTS.DBF из 1С, если установлена компонента УРБД и настроена распределенная база данных. Пример позволяет вывести объекты (например, элементы справочника товаров), по которым были зафиксированы изменения.

Чтобы добиться того же результата без компоненты УРБД, потребовалось бы заводить специальный справочник, и вводить в него значения при каждом сохранении, удалении, проведении, отмене проведения, пометке на удаление или снятии такой пометки у объекта, а также изменение времени, подчиненности и т.п.

А поскольку в Глобальном модуле 1С:Предприятие отслеживаются далеко не все подобные ситуации, то это гарантирует существенное дополнение конфигурации «следящим» за действиями пользователя кодом. В случае же использования компоненты УРБД в режиме мониторинга изменений, правка конфигурации не требуется совершенно – все изменения автоматически попадают в файл 1SUPDTS.DBF, и могут быть оттуда извлечены как ссылки на объекты.

///////////////////////////////////////////////////////////////////////
Процедура Выполнить()
dbf=СоздатьОбъект("XBASE");
ИмяФайла=КаталогИБ()+"1SUPDTS.DBF";
Если фс.СуществуетФайл(ИмяФайла)=0 Тогда
Сообщить("Таблица 1SUPDTS.DBF не найдена. Возможно, не установлена компонента УРБД.", "!");
Возврат;
КонецЕсли;
dbf.ОткрытьФайл(ИмяФайла,,1);
Если dbf.Открыта()=0 Тогда
Сообщить("Таблица 1SUPDTS.DBF заблокирована. Запустите 1С в разделенном (не монопольном) режиме.", "!");
Возврат;
КонецЕсли;
Если dbf.Первая()=0 Тогда
Сообщить("Файл 1SUPDTS.DBF пустой.");
Возврат
КонецЕсли;
Пока 1=1 Цикл
TYPEID=dbf.TYPEID;
стр=dbf.OBJID;
//Отделяем идентификатор базы (последние 3 символа)
ИДБазы=Прав(стр,3);
стр=Лев(стр, СтрДлина(стр)-3);
стр=СокрЛП(стр);
//Переводим в формат базы 1С
OBJID=_StrToID(стр);
тип=_StrToId(TYPEID);
//Дополняем пробелами слева
Пока СтрДлина(OBJID)<10 Цикл
OBJID=" "+OBJID;
КонецЦикла;
//Дополняем идентификатором базы
объ=""+OBJID+ИДБазы;
стр="{""B"",""0"",""0"","""+тип+""",""0"",""0"","""+объ+"""}";
о=ЗначениеИзСтрокиВнутр(стр); //справочник
Если ПустоеЗначение(о)=1 Тогда
стр="{""O"",""0"",""0"","""+тип+""",""0"",""0"","""+объ+"""}";
о=ЗначениеИзСтрокиВнутр(стр); //документ
КонецЕсли;
//выводит ссылки на объекты (например, названия товаров)
Сообщить("Объект: "+о);
Если dbf.Следующая()=0 Тогда
Прервать;
КонецЕсли;
КонецЦикла; //по записям DBF
dbf.ЗакрытьФайл();
КонецПроцедуры



Michail Varin пишет:
Приведенный код у меня заработал только после добавления строчки:
dbf.кодоваяСтраница(0);



Пример умеет работать только с документами и справочниками. Буквы (первый параметр ЗначениеИзСтрокиВнутр()) для других ссылочных типов:

B – Справочник
O - Документ
T – Счет
P – План счетов
K – Вид субконто
C – Календарь
A – Вид расчета

Этот пример, как и сам автообмен в УРБД, работает только в разделенном (не монопольном!) режиме 1С:Предприятие 7.7.


1SDWNLDS.DBF

Эта таблица хранит идентификаторы пакетов обмена.

DWNLDID (тип: Строка 9) – Идентификатор пакета выгрузки

DBSIGN (тип: Строка 3) – Код базы - получателя
DIRECT (тип: Строка 1) – Направление (I-входящий пакет или O-исходящий)

ACKNOWL (тип: Строка 1) – Наличие подтверждения доставки (символ А, если есть подтверждение, или пустая строка- если нет подтверждения)


Каждая выгрузка (например, инициированная через меню Администрирование – Распределенная ИБ – Автообмен) пишет в эту таблицу новую строчку с уникальным номером пакета DWNLDID. Этот же ключ будет проставлен всем объектам таблицы 1supdts.dbf, где оно еще пустое. Затем 1С «пройдется» по всем записям 1supdts.dbf, и выгрузит все указанные в нем объекты.

Что происходит, если объекты дошли до получателя

Объекты (элементы справочников и документы) идут в пакете с определенным номером пакета DWNLDID, и этот же номер будет фигурировать в подтверждении доставки. Программа увидит: ага, такой-то DWNLDID успешно дошел, и можно чистить таблицу 1supdts.dbf, в части тех записей об объектах, которые содержат этот же DWNLDID.

Что происходит, если объекты не дошли до получателя

Предположим, что наступил следующий день, и надо отправлять базе-получателю новую порцию свежевбитой пользователями информации. Часть объектов в таблице 1supdts.dbf будут с заполненными полями DWNLDID (это вчерашние объекты), а часть – с пустыми (сегодняшние объекты). УРБД пошлет все старые пакеты, по которым еще не было подтверждения, и один новый пакет (присвоив ему новый номер), в одном большом пакете. Таким образом, размер пакета выгрузки с каждым днем будет постоянно расти, до тех пор, пока не треснет что-либо, либо пока от базы – приемника не начнут приходить подтверждения. Предположим, что были доставлены пакеты с номерами 1 и 2, а всего было послано 3 пакета. Размер выгрузки немедленно уменьшится, поскольку УРБД удалит из 1supdts.dbf все записи об объектах, которые принадлежали пакетам 1 и 2 – ведь посылать их базе-приемнику больше не нужно.

Алгоритм повторной доставки

Вы можете реализовать подобные манипуляции с 1supdts.dbf вручную, если обмен производится, например, средствами XML. Алгоритм работы примерно следующий:

Заполнить все пустые поля DWNLDID значением нового (увеличенного на 1) идентификатора пакета.

Выгрузить все объекты, которые перечислены в 1supdts.dbf, указав в пакете выгрузки, какие номера DWNLDID были выгружены.
Если от базы-получателя приходит подтверждение по определенным DWNLDID, то удалить из 1supdts.dbf все записи, где DWNLDID совпадает с номерами пакетов с подтвержденной доставкой.

Ссылки

http://argat.h11.ru/URBDStructure.html
http://1c.proclub.ru/modules/newbb/viewtopic.php?topic_id=258258&forum=2&viewmode=flat&order=ASC&start=all
http://1c.realnet.ru/kuban/138067.html


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