Как в 1С 7.7 программно обойти все папки на диске и не прервать работу при ошибках доступа?

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

При разработке обработок для анализа файловой системы в среде 1С:Предприятие 7.7 программисты часто сталкиваются с проблемой прерывания выполнения кода. Типичная ситуация: ваша обработка сканирует дерево каталогов на системном диске и «спотыкается» на папках вроде Documents and Settings, System Volume Information или $RECYCLE.BIN. В современных версиях Windows (начиная с Windows 7) многие из этих путей являются не физическими папками, а точками соединения (Junction Points) или системными ссылками, доступ к которым ограничен даже для администратора. Если обращаться к ним напрямую через стандартные методы, программа выдает критическую ошибку и прекращает работу.

В этой статье мы подробно разберем, как грамотно построить алгоритм обхода папок, используя объект Scripting.FileSystemObject (FSO), и как сделать процесс устойчивым к ошибкам отсутствия прав доступа.

Причина возникновения ошибок доступа

Проанализируем ситуацию: в ОС Windows 7 и выше папка C:\Documents and Settings физически отсутствует. Это «символическая ссылка» для совместимости со старым ПО, которая перенаправляет запросы в C:\Users. На уровне прав NTFS для таких ссылок часто установлен запрет на «Чтение списка содержимого». Когда объект FileSystemObject пытается получить коллекцию подпапок (SubFolders) или вычислить размер (Size) такой папки, возникает исключение COM-объекта, которое 1С 7.7 не может обработать без специальных инструкций.

Решение 1: Использование блока Попытка — Исключение

Самый простой и эффективный способ в рамках 1С 7.7 — обернуть обращение к «опасным» свойствам объекта в конструкцию Попытка ... Исключение. Рассмотрим пример реализации обхода папок первого и второго уровня. Выясним, на каком этапе чаще всего происходят сбои.

Обычно ошибка возникает при попытке прочитать количество элементов в коллекции или при обращении к конкретному элементу. Разберем исправленный фрагмент кода:


// Перебор коллекции папок с обработкой ошибок
Для i = 0 по КолПапок - 1 Цикл
    // Получаем объект папки через вспомогательную функцию VBScript
    ы = глПолучитьЭлементКоллекцииПоНомеру(Коллекция1, i);    
    
    Попытка
        // Проверка свойства Size или Name часто инициирует проверку прав доступа
        // Если доступа нет, произойдет переход в блок Исключение
        Если ПустоеЗначение(ы.Size) = 0 Тогда
            ТЗ_Папки.НоваяСтрока();    
            ТЗ_Папки.ИмяПапки = ы.Name;
            ТЗ_Папки.ТипФайла = ы.Type;
            ТЗ_Папки.ПоложНаДиске = ы.Drive.Path;
            ТЗ_Папки.РодительскаяПапка = ы.ParentFolder.Name;
            ТЗ_Папки.ПолныйПуть = ы.Path;
            ТЗ_Папки.ДатаСозданияПапки = ы.DateCreated;
            ТЗ_Папки.ДатаПоследнегоДоступа = ы.DateLastAccessed;
            ТЗ_Папки.ДатаПоследнегоИзменения = ы.DateLastModified;
            ТЗ_Папки.Диск = БукваДиска;
            ТЗ_Папки.ДлинаПути = СтрДлина(СокрЛП(ы.Path));
        КонецЕсли;
    Исключение 
        // Если папка защищена или является некорректной ссылкой, 
        // мы просто игнорируем её и продолжаем цикл
        Сообщить("Нет доступа к объекту: " + ы.Path, "!");
    КонецПопытки;
КонецЦикла;

Важный нюанс: Обратите внимание, что в 1С 7.7 коллекции COM-объектов не всегда позволяют использовать стандартный цикл Для Каждого (который появился только в 8-й версии). Поэтому мы используем вспомогательный объект MSScriptControl.ScriptControl для обращения к элементам коллекции по индексу через VBScript.

Решение 2: Обработка ошибок внутри VBScript

Иногда ошибка внутри COM-объекта настолько критична, что 1С 7.7 «вылетает» до того, как сработает код в блоке Исключение. В этом случае мы можем перенести логику обработки ошибок непосредственно внутрь скрипта, который передается в MSScriptControl. Рассмотрим, как прописать игнорирование ошибок в VBS-коде.

Добавим директиву On Error Resume Next. Это позволит скрипту не прерываться, если коллекция подпапок недоступна.


Функция глПолучитьКолВоЭлементовКоллекции(Коллекция)
    ScrptCtrl = СоздатьОбъект("MSScriptControl.ScriptControl");
    ScrptCtrl.Language = "vbscript";
    ScrptCtrl.AddCode("
    |Function GetCountCollection(ObjSet)
    |   On Error Resume Next
    |   Count = 0
    |   If Not (ObjSet Is Nothing) Then
    |       Count = ObjSet.Count
    |   End If
    |   If Err.Number <> 0 Then Count = 0
    |   GetCountCollection = Count
    |End Function
    |");
    Возврат ScrptCtrl.Run("GetCountCollection", Коллекция);
КонецФункции

Использование On Error Resume Next гарантирует, что функция вернет 0 в случае проблем с правами, и основная программа на 1С продолжит выполнение без лишних диалоговых окон с ошибками.

Решение 3: Штатные средства ФС (Файловая Система)

Некоторые программисты предпочитают использовать встроенный объект 1С ФС. Методы НайтиПервыйФайл() и НайтиСледующийФайл() работают достаточно быстро, но имеют свои ограничения. Разберем их плюсы и минусы:

  1. Плюсы: Высокая скорость работы, отсутствие зависимости от внешних библиотек (COM/WSH).
  2. Минусы: Ограниченная информация о файлах. Вы не сможете легко получить дату создания или размер папки, не используя дополнительные вызовы АтрибутыФайла(). Также встроенные методы 1С 7.7 иногда некорректно работают с длинными путями (более 255 символов) и специфическими кодировками.

Проанализируем пример использования ФС для поиска:


ИмяФайла = "";
Каталог = "C:\";
Файл = ФС.НайтиПервыйФайл(Каталог + "*.*");
Пока ПустоеЗначение(Файл) = 0 Цикл
    Если (Файл <> ".") И (Файл <> "..") Тогда
        Атр = "";
        ФС.АтрибутыФайла(Каталог + Файл, , Атр);
        Если Сред(Атр, 4, 1) = "1" Тогда
            // Это папка, обрабатываем её
        КонецЕсли;
    КонецЕсли;
    Файл = ФС.НайтиСледующийФайл();
КонецЦикла;

Однако, как отмечают эксперты, методы ФС гарантированно работают только внутри каталога базы данных. При выходе «в дикую природу» системных дисков FileSystemObject оказывается гораздо мощнее и информативнее.

Решение 4: Использование WMI для повышения надежности

Если ваша задача — получить информацию о дисках и папках на системном уровне, рассмотрим использование WMI (Windows Management Instrumentation). Этот механизм позволяет делать запросы к операционной системе почти как к базе данных (WQL). Его главное преимущество — он часто позволяет прочитать метаданные о папке даже тогда, когда прямой доступ к её содержимому через проводник или FSO закрыт.

Пример получения списка логических дисков через WMI:


Локатор = СоздатьОбъект("WbemScripting.SWbemLocator");
Сервис = Локатор.ConnectServer(".");
Объекты = Сервис.ExecQuery("Select * from Win32_LogicalDisk Where DriveType = 3"); // Только жесткие диски
// Далее перебор коллекции Объекты

WMI работает медленнее, чем FSO, но он незаменим для системного администрирования и сбора информации о «проблемных» дисках.

Рекомендации по оптимизации

Для создания действительно надежной обработки по сканированию файлов в 1С 7.7 придерживайтесь следующих правил:

  1. Проверка готовности диска: Перед началом обхода всегда проверяйте свойство Drive.IsReady. Обращение к пустому дисководу или картридеру вызовет длительное зависание системы.
  2. Фильтрация системных путей: Заранее создайте список исключений (СписокЗначений), в который внесите $RECYCLE.BIN, System Volume Information и прочие служебные каталоги. Это сэкономит время и избавит от лишних срабатываний блока Исключение.
  3. Запуск от имени администратора: Помните, что 1С 7.7 — старое приложение. Чтобы FSO имел доступ к большинству папок в Windows 10, запускайте 1С через правую кнопку мыши — «От имени администратора».
  4. Использование коротких путей: Если вы сталкиваетесь с ошибками на папках с очень длинными именами, попробуйте обращаться к свойству ShortPath (формат 8.3), которое предоставляет FileSystemObject.

Подведем итог: использование Scripting.FileSystemObject в связке с MSScriptControl и обязательной обработкой ошибок через Попытка — Исключение является «золотым стандартом» для работы с файловой системой в 1С 7.7. Это позволяет обходить системные ограничения современных ОС и создавать отказоустойчивые инструменты для работы с данными.

← На главную