Часто возникает задача синхронизации бумажного или электронного архива с базой данных 1С. Например, когда в определенной папке на сервере хранятся сканы документов, и нам нужно быстро увидеть в интерфейсе программы только те документы, файлы которых уже присутствуют в этой папке. Рассмотрим подробно, как реализовать такой механизм с использованием встроенного языка 1С, на что обратить внимание при работе с путями и как правильно наложить фильтр на форму списка.
Основная проблема заключается в том, что 1С — это база данных, а папка на диске — это внешняя среда. Чтобы их подружить, нам нужно выполнить три этапа:
Важно учитывать, где физически находится папка. Если она на сервере, то и код должен исполняться на стороне сервера под учетной записью, от имени которой запущена служба 1С.
Для работы с файловой системой мы используем метод НайтиФайлы. Разберем пример кода, который можно разместить в модуле формы списка. Проанализируем ситуацию: нам нужно получить массив номеров, которые мы затем будем искать в базе.
&НаСервере
Функция ПолучитьСписокНомеровИзПапки(ПутьКПапке)
СписокНомеров = Новый Массив;
// Используем маску "*" для поиска всех файлов или "*.pdf" для конкретных типов
МассивФайлов = НайтиФайлы(ПутьКПапке, "*.*");
Для Каждого Файл Из МассивФайлов Цикл
// Игнорируем директории, если они есть в папке
Если Файл.ЭтоДиректория() Тогда
Продолжить;
КонецЕсли;
// Получаем имя без расширения (например, из "000125.pdf" получим "000125")
ЧистыйНомер = Файл.ИмяБезРасширения;
СписокНомеров.Добавить(ЧистыйНомер);
КонецЦикла;
Возврат СписокНомеров;
КонецФункции
Обратите внимание на важный нюанс: метод ИмяБезРасширения объекта Файл позволяет нам сразу избавиться от .doc или .pdf. Если этого не сделать, поиск по номеру документа в 1С не даст результатов, так как номера в базе хранятся в чистом виде.
При сравнении строк "125" и "000000125" система скажет, что они не равны. В 1С номера документов часто имеют фиксированную длину с лидирующими нулями. Если файлы в папке называются просто "125.pdf", нам придется программно дополнить их нулями до нужной длины или использовать преобразование типов.
Рассмотрим, как привести номер из файла к формату номера 1С. Допустим, длина номера в вашем документе составляет 11 символов:
// Дополнение строки нулями слева
Пока СтрДлина(ЧистыйНомер) < 11 Цикл
ЧистыйНомер = "0" + ЧистыйНомер;
КонецЦикла;
Если в системе используются префиксы (например, "БП-"), их также необходимо добавлять к номеру перед поиском, либо очищать номер в запросе, что технически сложнее и медленнее.
Многие начинающие разработчики совершают ошибку: они выполняют запрос к базе данных, получают результат в выборку, но не знают, что делать с ней дальше. Для формы списка правильным решением будет не перебор выборки, а установка Отбора в свойстве Список (который является ДинамическимСписком).
Разберем процедуру, которая вызывается при нажатии кнопки на форме:
&НаКлиенте
Процедура КомандаФильтрПоФайлам(Команда)
ПутьКПапке = "\\Server\ScanArchive\"; // Используйте UNC-пути для сетевых папок
СписокНомеров = ПолучитьСписокНомеровИзПапки(ПутьКПапке);
Если СписокНомеров.Количество() = 0 Тогда
Сообщить("В указанной папке файлы не найдены.");
Возврат;
КонецЕсли;
УстановитьФильтрНаСписке(СписокНомеров);
КонецПроцедуры
&НаСервере
Процедура УстановитьФильтрНаСписке(МассивНомеров)
// Очищаем старые отборы по полю "Номер"
ИмяПоля = "Номер";
ПолеКомпоновки = Новый ПолеКомпоновкиДанных(ИмяПоля);
Для Каждого ЭлементОтбора Из Список.Отбор.Элементы Цикл
Если ТипЗнч(ЭлементОтбора) = Тип("ЭлементОтбораКомпоновкиДанных")
И ЭлементОтбора.ЛевоеЗначение = ПолеКомпоновки Тогда
Список.Отбор.Элементы.Удалить(ЭлементОтбора);
КонецЕсли;
КонецЦикла;
// Добавляем новый отбор типа "В списке"
НовыйОтбор = Список.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
НовыйОтбор.ЛевоеЗначение = ПолеКомпоновки;
НовыйОтбор.ВидСравнения = ВидСравненияКомпоновкиДанных.ВСписке;
НовыйОтбор.ПравоеЗначение = МассивНомеров;
НовыйОтбор.Использование = Истина;
НовыйОтбор.РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.БыстрыйДоступ;
КонецПроцедуры
Использование ВидСравненияКомпоновкиДанных.ВСписке — это наиболее эффективный способ. Мы передаем массив всех найденных номеров сразу, и платформа сама оптимизирует запрос для отображения нужных строк.
Проанализируем ситуацию, когда код "отказывается работать" без видимых ошибок. Чаще всего это связано с правами доступа и контекстом исполнения.
1. Права службы 1С (Server-side)
Если вы запускаете НайтиФайлы на сервере, помните: сервер 1С работает под своей технической учетной записью (обычно usr1cv8). Эта учетная запись "не видит" ваши личные сетевые диски (например, диск Z:, который вы подключили себе на компьютере). Путь обязательно должен быть UNC (вида \\ИмяСервера\Папка\), и у пользователя usr1cv8 должны быть права "Чтение" на эту сетевую шару.
2. Интерактивный выбор папки
Если вы хотите, чтобы пользователь сам выбирал папку, используйте ДиалогВыбораФайла с режимом ВыборКаталога на клиенте, а затем передавайте выбранный путь на сервер для обработки.
3. Производительность
Если в папке находятся десятки тысяч файлов, метод НайтиФайлы может выполняться долго, что приведет к "зависанию" интерфейса. В таких случаях рекомендуется:
Мы рассмотрели комплексный подход к решению задачи. Ключевой успех здесь кроется в правильной предобработке имен файлов и грамотном использовании механизмов компоновки данных. Реализовав очистку номера от расширения и установив программный отбор ВСписке, вы получите удобный и быстрый инструмент для работы с документами.