Получение значений периодических реквизитов из 1С7.7
Встала проблема получения значений периодичсеких реквизитов.
После всяческого шаманства со стандартной утилитой пришел к выводу что стандартными инструементами этого добиться нельзя.
Пока родилось только одно решение проблемы:
В 1С при создании объекта для работы со справочником можно зафиксировать дату установки периодических реквизитов, после чего далее можно с реквизитами работать как с обычными.
Например:
спр=СоздатьОбъект("Справочник.Валюты");
спр.ИспользоватьДату('01.01.2002');
Идея возникла такая - так как практически всегда при синхронизации интересуют только текущие даты, можно скопировать скрипт, содержащий утилиты для работы с 1С (в моем случае scr_Dataflow1CUtils_V77) и поправить в нем процедуру создания объекта для работы в 1С, добавив метод "ИспользоватьДату", с текущей датой. Назвать такой варинат скрипта как нибудь типа scr_Dataflow1CUtils_V77_Periodic и в скрипте синхронизации обращаться не к scr_Dataflow1CUtils, а тоже к его копии с другим именем, которая будет вызывать изменнный scr_Dataflow1CUtils_V77_Periodic.
В таком случае весь стандартный функционал утилиты для интеграции должен дальше работать нормально.
Решение конечно неуклюжее, но лучше пока ничего не придумалось.
Вопрос собственно в том, подскажите, в какой именно функции в scr_Dataflow1CUtils_V77 создается объект для работы интеграции, с ходу найти не удалось.
Нравится
Подумал, что можно проще:
Вставил скрипт в синхроизацию:
function OnBeforeImport(Param, Dataset, Query, Attributes) {
var CurrentObject = Param.Object1C;
CurrentObject.UseDate('06.06.11',1);
}
по идее тут должен примениться метод .ИсползоватьДату (UseDate анг. синоном) к текущему справочнику ПТО
в котором есть периодический реквизит Контрагент, являющийся ссылкой на справочник Контрагенты. Судя по мануалам 1с, далее с объектом должна идти работа как с обычными реквизитами.
Однако Select1C.Контрагент.Наименование выдает NULL...
Должен работать примерно такой код:
var Spr= Param.Object1C.CreateObject([Имя справочника]);
Spr.getAttrib([Аттрибут]).Получить([Дата]));
только вначале нужно его найти
по наименованию
Spr.FindByDescr([Наименование],0)
по аттрибуту
Spr.FindByAttribute([Имя Аттрибута],[Аттрибут],1)
или по коду
Spr.FindByCode([Код],0)=1;
и ИМХО лучше использовать русские аналоги комманд
Немного не то, мне кажется. Если я ковыряюсь в скрипте непосредственно синхронизации - то объект уже создан. Осталось применить к нему метод ИспользоватьДату(), чтобы получить периодические значения на дату и дальше обращаться обычным путем к реквизитам. Вот применить метод и не получается.
function OnBeforeImport(Param, Dataset, Query, Attributes) { var Account = Select1C[QueryLink].Контрагент.Получить(); var AccountName = Account.Наименование; Account = System.EmptyValue; }
Функция "Получить()" принимает параметр типа Дата, с помощью нее можно получить значение периодического реквизита на определенную дату. Если параметр не указан возвращается значение на текущую дату (последнее значение).
Пример импорта курса валют из периодического реквизита "Курс"
Настраивается импорт справочника Валюты, после чего дописываем в скрипте следущее:
function OnAfterRecordImport(Param, Dataset, Select1C) { debugger; var Dictionary = GetNewDictionary(); Dictionary('CurrencyID') = Param.RecordTSID; scr_DataflowUtils.DeleteRecords('tbl_CurrencyRate', Dictionary); var Periodic = Param.Obj1C.CreateObject('Periodic'); Periodic.ИспользоватьОбъект("Курс", Select1C[QueryLink]); Periodic.ОбратныйПорядок(0); Periodic.ВыбратьЗначения(); var Rate; var For = Select1C[QueryLink].Кратность; var StartDate = null; var DueDate; while (Periodic.ПолучитьЗначение()) { Rate = Periodic.Значение; DueDate = new Date(Periodic.ДатаЗнач); DueDate.setDate(DueDate.getDate() -1); AddCurrencyRate(StartDate, DueDate, Rate, For, Param.RecordTSID); StartDate = new Date(Periodic.ДатаЗнач); } AddCurrencyRate(StartDate, new Date(System.Now()), Rate, For, Param.RecordTSID); Periodic = System.EmptyValue; }
"Кривонос Максим" написал:function OnBeforeImport(Param, Dataset, Query, Attributes) {
var Account = Select1C[QueryLink].Контрагент.Получить();
}
Вот эта конструкция вываливается с ошибкой при любом раскладе.
PS: А ведь Select1C не присутствует в параметрах OnBeforeImport... Не потому ли ошибка?
Действительно опечатка...
Функция OnBeforeImport срабатывает лишь один раз в самом начале импорта еще до выполнения запроса в 1С.
Нам же нужно это значение для каждой записи 1С, поэтому необходимо писать обработчик в функции
OnBeforeRecordImport(Param, Dataset, Select1C)
Да, все заработало. Последний вопрос в догонку - ставлю строку:
Dataset('Name') = Account.Наименование;
все ок наименование присваивается, но каждый раз одному и тому же контрагенту, то есть записи не добавляются. Как после заполния значений переходить к новому датасету?
Все, разобрался. В настройках интеграции свел два поля Object1C и Code1C, сделал код ключевым, остальные поля через скрипт (Наименование, и прочее). Все заработало как надо, дубли не плодятся. Спасибо!