Как сравнить номера документов в папке на компьютере и в 1С с последующей фильтрацией списка

Программист 1С v8.3 (Управляемые формы)
← На главную

Часто возникает задача синхронизации бумажного или электронного архива с базой данных 1С. Например, когда в определенной папке на сервере хранятся сканы документов, и нам нужно быстро увидеть в интерфейсе программы только те документы, файлы которых уже присутствуют в этой папке. Рассмотрим подробно, как реализовать такой механизм с использованием встроенного языка 1С, на что обратить внимание при работе с путями и как правильно наложить фильтр на форму списка.

Постановка задачи и выбор стратегии

Основная проблема заключается в том, что 1С — это база данных, а папка на диске — это внешняя среда. Чтобы их подружить, нам нужно выполнить три этапа:

  1. Просканировать папку и получить список имен файлов.
  2. Очистить имена от лишней информации (расширений, префиксов).
  3. Применить фильтр к динамическому списку в форме 1С, чтобы отобразить только совпадения.

Важно учитывать, где физически находится папка. Если она на сервере, то и код должен исполняться на стороне сервера под учетной записью, от имени которой запущена служба 1С.

Этап 1. Получение списка файлов с помощью НайтиФайлы

Для работы с файловой системой мы используем метод НайтиФайлы. Разберем пример кода, который можно разместить в модуле формы списка. Проанализируем ситуацию: нам нужно получить массив номеров, которые мы затем будем искать в базе.


&НаСервере
Функция ПолучитьСписокНомеровИзПапки(ПутьКПапке)
    
    СписокНомеров = Новый Массив;
    // Используем маску "*" для поиска всех файлов или "*.pdf" для конкретных типов
    МассивФайлов = НайтиФайлы(ПутьКПапке, "*.*");
    
    Для Каждого Файл Из МассивФайлов Цикл
        // Игнорируем директории, если они есть в папке
        Если Файл.ЭтоДиректория() Тогда
            Продолжить;
        КонецЕсли;
        
        // Получаем имя без расширения (например, из "000125.pdf" получим "000125")
        ЧистыйНомер = Файл.ИмяБезРасширения;
        СписокНомеров.Добавить(ЧистыйНомер);
    КонецЦикла;
    
    Возврат СписокНомеров;
    
КонецФункции

Обратите внимание на важный нюанс: метод ИмяБезРасширения объекта Файл позволяет нам сразу избавиться от .doc или .pdf. Если этого не сделать, поиск по номеру документа в 1С не даст результатов, так как номера в базе хранятся в чистом виде.

Этап 2. Проблема лидирующих нулей и префиксов

При сравнении строк "125" и "000000125" система скажет, что они не равны. В 1С номера документов часто имеют фиксированную длину с лидирующими нулями. Если файлы в папке называются просто "125.pdf", нам придется программно дополнить их нулями до нужной длины или использовать преобразование типов.

Рассмотрим, как привести номер из файла к формату номера 1С. Допустим, длина номера в вашем документе составляет 11 символов:


// Дополнение строки нулями слева
Пока СтрДлина(ЧистыйНомер) < 11 Цикл
    ЧистыйНомер = "0" + ЧистыйНомер;
КонецЦикла;

Если в системе используются префиксы (например, "БП-"), их также необходимо добавлять к номеру перед поиском, либо очищать номер в запросе, что технически сложнее и медленнее.

Этап 3. Фильтрация динамического списка в форме

Многие начинающие разработчики совершают ошибку: они выполняют запрос к базе данных, получают результат в выборку, но не знают, что делать с ней дальше. Для формы списка правильным решением будет не перебор выборки, а установка Отбора в свойстве Список (который является ДинамическимСписком).

Разберем процедуру, которая вызывается при нажатии кнопки на форме:


&НаКлиенте
Процедура КомандаФильтрПоФайлам(Команда)
    
    ПутьКПапке = "\\Server\ScanArchive\"; // Используйте UNC-пути для сетевых папок
    СписокНомеров = ПолучитьСписокНомеровИзПапки(ПутьКПапке);
    
    Если СписокНомеров.Количество() = 0 Тогда
        Сообщить("В указанной папке файлы не найдены.");
        Возврат;
    КонецЕсли;
    
    УстановитьФильтрНаСписке(СписокНомеров);
    
КонецПроцедуры

&НаСервере
Процедура УстановитьФильтрНаСписке(МассивНомеров)
    
    // Очищаем старые отборы по полю "Номер"
    ИмяПоля = "Номер";
    ПолеКомпоновки = Новый ПолеКомпоновкиДанных(ИмяПоля);
    
    Для Каждого ЭлементОтбора Из Список.Отбор.Элементы Цикл
        Если ТипЗнч(ЭлементОтбора) = Тип("ЭлементОтбораКомпоновкиДанных") 
            И ЭлементОтбора.ЛевоеЗначение = ПолеКомпоновки Тогда
            Список.Отбор.Элементы.Удалить(ЭлементОтбора);
        КонецЕсли;
    КонецЦикла;
    
    // Добавляем новый отбор типа "В списке"
    НовыйОтбор = Список.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
    НовыйОтбор.ЛевоеЗначение  = ПолеКомпоновки;
    НовыйОтбор.ВидСравнения   = ВидСравненияКомпоновкиДанных.ВСписке;
    НовыйОтбор.ПравоеЗначение = МассивНомеров;
    НовыйОтбор.Использование  = Истина;
    НовыйОтбор.РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.БыстрыйДоступ;

КонецПроцедуры

Использование ВидСравненияКомпоновкиДанных.ВСписке — это наиболее эффективный способ. Мы передаем массив всех найденных номеров сразу, и платформа сама оптимизирует запрос для отображения нужных строк.

Важные технические моменты и нюансы доступа

Проанализируем ситуацию, когда код "отказывается работать" без видимых ошибок. Чаще всего это связано с правами доступа и контекстом исполнения.

1. Права службы 1С (Server-side)

Если вы запускаете НайтиФайлы на сервере, помните: сервер 1С работает под своей технической учетной записью (обычно usr1cv8). Эта учетная запись "не видит" ваши личные сетевые диски (например, диск Z:, который вы подключили себе на компьютере). Путь обязательно должен быть UNC (вида \\ИмяСервера\Папка\), и у пользователя usr1cv8 должны быть права "Чтение" на эту сетевую шару.

2. Интерактивный выбор папки

Если вы хотите, чтобы пользователь сам выбирал папку, используйте ДиалогВыбораФайла с режимом ВыборКаталога на клиенте, а затем передавайте выбранный путь на сервер для обработки.

3. Производительность

Если в папке находятся десятки тысяч файлов, метод НайтиФайлы может выполняться долго, что приведет к "зависанию" интерфейса. В таких случаях рекомендуется:

Заключение

Мы рассмотрели комплексный подход к решению задачи. Ключевой успех здесь кроется в правильной предобработке имен файлов и грамотном использовании механизмов компоновки данных. Реализовав очистку номера от расширения и установив программный отбор ВСписке, вы получите удобный и быстрый инструмент для работы с документами.

← На главную