Оригинал статьи: 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 = ""; КонецПроцедуры
После чего нужна процедура для запуска каждой из баз списка сосчитыванием и сохранением проводок для последующего их анализа.