В процессе работы с распределенными информационными базами (УРБД) на платформе 1С:Предприятие 7.7 часто возникает ситуация, когда документы, созданные в центральной базе (ЦБ), не попадают в периферийную (ПБ). Это происходит из-за установленных правил миграции в конфигураторе (например, «Место создания и центр»). Если документ был создан в Центре, он там и остается. Разберемся, как можно «обмануть» систему и принудительно заставить несколько конкретных документов уйти в нужную периферийную базу, не меняя глобально правила миграции для всей системы.
Это самый простой, но «массивный» способ. Рассмотрим его алгоритм:
Важное замечание: Главный минус этого метода в том, что если за время, пока миграция была изменена на «Все ИБ», кто-то отредактирует другие документы этого же типа, они тоже «полетят» во все периферийные базы, что может существенно увеличить объем файлов обмена.
Проанализируем более изящный способ, который не требует изменения метаданных и безопасен для ссылочной целостности базы. Этот метод основан на том, что документы, созданные в периферии, всегда мигрируют в центр.
Разберем процесс по шагам:
Этот способ хорош тем, что мы не нарушаем внутренние идентификаторы ID объектов и не лезем в системные таблицы базы данных.
Для опытных программистов существует возможность принудительно добавить документ в очередь выгрузки через системную таблицу _1supdts. В этой таблице 1С хранит информацию о том, какие объекты должны быть переданы в конкретные базы.
Посмотрим на структуру полей таблицы _1supdts:
Если вы используете SQL-версию 1С 7.7, можно выполнить прямой запрос. Рассмотрим пример кода для регистрации документа:
// Пример кода для регистрации объекта в таблице изменений через ODBC
ТекстЗапросаОтсылки = "
|declare @SelectedId char(9)
|declare @SelectedDef int
|declare @SelectedSign char(3)
|declare @count int
|set @SelectedId=?
|set @SelectedDef=?
|set @SelectedSign=?
|-- Увеличиваем версию в журнале для фиксации изменений
|update _1sjourn set verstamp=(select verstamp from _1sjourn where iddocdef=@SelectedDef and iddoc=@SelectedId)+1
|where iddocdef=@SelectedDef and iddoc=@SelectedId
|-- Проверяем, нет ли уже такой регистрации
|set @count = (select count(*) from _1supdts where typeid=@SelectedDef and objid=@SelectedId and dbsign=@SelectedSign)
|if @Count=0
|begin
| insert into _1supdts values ( @SelectedSign, @SelectedDef, @SelectedId, ' ', ' ')
|end
|else
|begin
| update _1supdts set dwnldid= '' where Typeid=@SelectedDef and Objid=@SelectedId and DBSign=@SelectedSign
|end";
Важно: При использовании этого метода нужно быть осторожным. Если документ имеет движения по регистрам, то просто передача «шапки» документа может не привести к появлению движений в ПБ. В таком случае в периферии документ придется перепровести программно после загрузки.
Рассмотрим еще одну ситуацию: вы хотите, чтобы документ физически стал «периферийным». В 1С 7.7 идентификатор объекта ID содержит в себе префикс базы, в которой он был создан (последние 3 символа 36-ричного кода).
Можно пойти по пути подмены ID документа в центральной базе на ID, который якобы принадлежит периферии. Однако проанализируем риски: ID документа прописан во многих местах — в таблице журнала _1sjourn, в шапке документа, в табличных частях, в движениях регистров и операциях. Если вы решите менять ID, вам придется обновлять его во всех связанных таблицах. Это крайне трудозатратный и опасный метод, который мы рекомендуем использовать только в самых крайних случаях и только при наличии полных бэкапов.
Если вам нужно перебросить всего пару документов разово, самым стабильным будет Метод №2 (через пустышки). Он гарантирует, что 1С сама отработает все механизмы записи и движений.
Если же такая необходимость возникает регулярно, стоит написать небольшую процедуру на основе Метода №3. Выясним, как программно получить нужные ID для регистрации в _1supdts. Для этого можно использовать компоненту 1С++ или штатные средства работы со строковыми идентификаторами объектов (например, метод ЗначениеВСтрокуВнутр() позволяет вычленить ID объекта).
Например, функция для регистрации документа может выглядеть так:
Процедура глЗарегистрироватьДокументДляПБ(КонтДок, КодБазыПБ)
// Получаем внутренний ID документа
ИдДок = СокрЛП(Сред(ЗначениеВСтрокуВнутр(КонтДок), 24, 9));
// Получаем ID вида документа (метаданные)
ИдВида = глПолучитьИдВида(КонтДок.Вид());
// Выполняем SQL или DBF вставку в таблицу _1supdts
// (Логика вставки аналогична приведенной выше в методе 3)
КонецПроцедуры
Помните, что принудительная миграция — это всегда вмешательство в логику распределенной системы. После выполнения таких операций всегда проверяйте соответствие остатков в Центре и Периферии по перенесенным документам.