Оригинал статьи: http://www.it-tex.ru/index.php?id_razdel=1&id_mat=4
У программистов, работающих в аудиторских фирмах или в головной организации холдинговых структур, использующих для ведения бух. учета конфигурацию "Бухгалтерия" , возникает проблема по сбору (возможно, для последующего анализа) данных из разных каталогов.
Если такой сбор данных нужен лишь один раз - в принципе, не так уж сложно зайти вручную в каждую базу и запустить некую процедуру, хотя даже и в этом случае, настоящий программист лучше два дня будет писать код, чем в течение одного дня сто раз повторять одни и те же нехитрые действия (запустить базу, открыть внешний отчет, нажать кнопку "Сформировать", закрыть базу). Тем более если этот сбор данных нужно проводить периодически. Тогда написанию программы альтернативы нет. (Ну разве что начальство подберет сотрудника в ваш отдел на должность "Оператор по запуску внешних отчетов 1С" : ).
Предположим, у вас есть пятьдесят каталогов с информационными базами, среди них есть несколько, между которыми происходят взаимные отгрузка и оприходывание товара, и проследить нет ли расхождений (поступление в базе X = отгрузка в базе Y ) в учете этих операций в соответствующих базах.
Для начала нам нужно получить список (который лучше всего оформить как справочник в составе конфигурации) каталогов информационных баз. Если Вы - настоящий программист, тогда Вы не будете набивать каталоги в список, а вдруг место расположение каталогов изменится? Нужно делать процедуру сбора сведений о каталогах. Выберем простейший вариант - любой каталог, где есть файл 1Cv7.MD (кроме NEW_STRU) - и есть каталог ИБ.
Процедура собратьФайлы(начПуть,тзФайлы)
сзКаталоги = СоздатьОбъект("СписокЗначений");
Если Прав(СокрЛП(начПуть),1)=":" Тогда
ФС.УстТекКаталог(СокрЛП(начПуть)+"");
Иначе
ФС.УстТекКаталог(СокрЛП(начПуть));
КонецЕсли;
стр=ФС.НайтиПервыйФайл("*.*");
глВрПослДоступа = "";
Пока СокрЛП(стр)"" Цикл
аф = "";
имя = "";
рф = 0;
врПослДоступа = "";
ФС.АтрибутыФайла( СокрЛП(стр),рф,аф,,,врПослДоступа,имя );
Если Лев(стр,1)"." Тогда
Если Сред(аф,4,1)="1" Тогда //каталог
сзКаталоги.ДобавитьЗначение(СокрЛП(начПуть)+""+СокрЛП(стр));
Иначе
Если СокрЛп(Нрег(стр))="1cv7.md" Тогда
Если Найти(ВРЕГ(начПуть),"NEW_STRU")=0 Тогда
Сообщить(начПуть);
тзФайлы.НоваяСтрока();
тзФайлы.Путь = начПуть;
тзФайлы.ВремяДатаОбращения = глВрПослДоступа;
Если СокрЛП(глВрПослДоступа)"" Тогда
Прервать;
КонецЕсли;
КонецЕсли;
ИначеЕсли СокрЛп(Врег(стр))="1SUSERS.DBF" Тогда
Если Найти(ВРЕГ(начПуть),"NEW_STRU")=0 Тогда
глВрПослДоступа = врПослДоступа;
Если СокрЛП(тзФайлы.ВремяДатаОбращения)="" Тогда
тзФайлы.ВремяДатаОбращения = глВрПослДоступа;
Прервать;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
стр=ФС.НайтиСледующийФайл();
КонецЦикла;
Для инд=1 по сзКаталоги.РазмерСписка() Цикл
собратьФайлы( сзКаталоги.ПолучитьЗначение(инд),тзФайлы );
КонецЦикла;
КонецПроцедуры
Это рекурсивная процедура, в параметры которой передается начальный путь сбора файлов и таблица значений, в которую мы и сохраним пути всех найденных ИБ.
Пример вызова:
тзБазы = СоздатьОбъект("ТаблицаЗначений");
тзБазы.НоваяКолонка("Путь");
тзБазы.НоваяКолонка("ВремяДатаОбращения");
собратьФайлы(«С:bases»,тзБазы);
Получив этот список путей, занесем его в реквизить "Путь" справочника "Базы1С" для дальнейшей обработки.
сБазы = СоздатьОбъект("Справочник.Базы1С");
сБазыДляЗ = СоздатьОбъект("Справочник.Базы1С");
// НеНайдена=1 для ненайденных баз
сБазы.ВыбратьЭлементы();
Пока сБазы.ПолучитьЭлемент()=1 Цикл
Состояние("1) Обрабатываются: "+сБазы.Путь);
Если (сБазы.ПометкаУдаления()=1) ИЛИ (сБазы.ЭтоГруппа()=1) Тогда
Продолжить;
КонецЕсли;
хСтр="";
сБазыДляЗ.НайтиЭлемент( сБазы.ТекущийЭлемент() );
Если тзБазы.НайтиЗначение(СокрЛП(сБазы.Путь),хСтр,1)=1 Тогда
сБазыДляЗ.НеНайдена = 0;
Иначе
сБазыДляЗ.НеНайдена = 1;
КонецЕсли;
сБазыДляЗ.Записать();
КонецЦикла;
// Обновить существующие базы и добавить новые в список
тзБазы.ВыбратьСтроки();
Пока тзБазы.ПолучитьСтроку()=1 Цикл
Состояние("2) Обрабатываются: "+тзБазы.Путь);
Путь = тзБазы.Путь;
Если сБазы.НайтиПоРеквизиту( "Путь",Путь,1)=0 Тогда
сБазы.Новый();
сБазы.Путь = Путь;
КонецЕсли;
Если безРазм=0 Тогда
сБазы.РазмерБД = размерКаталога(Путь);
КонецЕсли;
сБазы.ВремяДатаОбращения = тзБазы.ВремяДатаОбращения;
сБазы.Записать();
КонецЦикла;
Далее нужно запрограммировать и запустить процедурку для каждого пути из списка, которая считает информацию о базе и запишет ее в реквизиты "НазваниеОрганизации", "ИннОрганизации", "Примечание".
Процедура максСчитатьБазу(Б1С,Элем)
V7 = "";
Если ФС.СуществуетФайл(Б1С.Путь + "NUL") = 0 Тогда
Сообщить("Путь информационной базы не найден - +Б1С.Путь+ !");
Иначе
V7 = СоздатьОбъект("V77.Application");
Сообщить("Открывается база "+Б1С.Путь+" ...");
Открыта = 0;
СтрокаЗапуска = "";
Попытка
Если ПустоеЗначение(Б1С.Пользователь)=0 Тогда
СтрокаЗапуска = "/d"+Симв(34)+СокрЛП(Б1С.Путь)+Симв(34)+
" /M /N"+СокрЛП(Б1С.Пользователь)+" /P"+СокрЛП(Б1С.Пароль);
Открыта = V7.Initialize(V7.RMTrade, СтрокаЗапуска, "NO_SPLASH_SHOW");
Иначе
СтрокаЗапуска ="/d" +Симв(34)+ СокрЛП(Б1С.Путь) +Симв(34)+
" /M";
Открыта = V7.Initialize(V7.RMTrade, СтрокаЗапуска , "NO_SPLASH_SHOW");
КонецЕсли;
Исключение
Сообщить( "СтрокаЗапуска=+СтрокаЗапуска+","!!!");
Сообщить( ОписаниеОшибки(),"!!!" );
КонецПопытки;
Если Открыта = 0 Тогда
Сообщить("Ошибка открытия информационной базы - "+Б1С.Путь);
V7 = "";
Предупреждение("Ошибка открытия информационной базы.");
КонецЕсли;
КонецЕсли;
//
Если V7 = "" Тогда
Возврат;
КонецЕсли;
Сообщить("Открыта.");
//
БК = V7.EvalExpr("Константа");//"СоздатьОбъект("+Симв(34)+"Константа"+Симв(34)+")");
Попытка
Б1С.Фирма_Наименование = БК.ПолучитьАтрибут("НазваниеОрганизации");
Исключение
Сообщить("Не получено название организации.","!!!");
КонецПопытки;
Попытка
Б1С.Фирма_ИНН = БК.ПолучитьАтрибут("ИННОрганизации");
Исключение
Сообщить("Не получен ИНН организации.","!!!");
КонецПопытки;
Б1С.Примечание = V7.EvalExpr("ЗаголовокСистемы()");
Если ПустоеЗначение(Б1С.Примечание)=1 Тогда
Б1С.Примечание = Б1С.Фирма_Наименование;
Если ПустоеЗначение(Б1С.Примечание)=1 Тогда
Б1С.Примечание = "?";
КонецЕсли;
КонецЕсли;
Б1С.Наименование = Б1С.Примечание;
Попытка
Б1С.Записать();
Исключение
Сообщить(ОписаниеОшибки(),"!!!");
КонецПопытки;
//
V7.ExecuteBatch("ЗавершитьРаботуСистемы(0)");
V7 = "";
КонецПроцедуры
После чего нужна процедура для запуска каждой из баз списка со считыванием и сохранением проводок для последующего их анализа.
Начать дискуссию