При разработке на платформе 1С:Предприятие 7.7 программисты часто сталкиваются с проблемой некорректного отображения кириллицы (так называемых «крякозябр») при попытке получить список файлов из папки. Типичная ситуация: использование команды DIR через КомандаСистемы с выводом результата в текстовый файл, который затем считывается объектом Текст. Давайте разберем, почему это происходит и как решить задачу правильно.
Проанализируем ситуацию: стандартная командная строка Windows (cmd.exe) по умолчанию работает в кодировке OEM (CP866), которая является наследницей кодировки DOS. В то же время 1С:Предприятие 7.7 и её объект Текст ожидают данные в кодировке ANSI (Windows-1251).
Когда мы выполняем команду типа DIR > files.txt, названия файлов, содержащие кириллические символы, записываются в файл в формате CP866. При последующем открытии этого файла методом Открыть() в 1С, программа интерпретирует байты CP866 по таблице Windows-1251, что и порождает нечитаемые символы. Рассмотрим подробнее способы исправления этой ситуации.
Самый простой и эффективный способ, который рекомендуют опытные разработчики — это отказ от внешних системных команд в пользу встроенных механизмов платформы. Это позволяет избежать проблем с кодировками, так как 1С сама корректно обрабатывает имена файлов в своей среде. Разберем по шагам реализацию через функции НайтиПервыйФайл и НайтиСледующийФайл.
Посмотрим на пример кода, который заменяет выгрузку во внешний файл:
ИмяФайла = "";
ПутьКПапке = "C:\MyFiles\";
Маска = "*.txt";
// Начинаем поиск первого файла
Файл = НайтиПервыйФайл(ПутьКПапке + Маска);
Пока ПустаяСтрока(Файл) = 0 Цикл
// Здесь мы сразу получаем корректное имя файла в Windows-1251
Сообщить("Найден файл: " + Файл);
// Выполняем необходимые действия с файлом...
// Переходим к следующему файлу
Файл = НайтиСледующийФайл();
КонецЦикла;
Использование этого метода полностью снимает проблему «крякозябр», так как данные не покидают адресное пространство 1С и не перекодируются в DOS-формат.
Если штатных функций 1С по какой-то причине недостаточно (например, требуется работа с длинными путями или специфическими атрибутами), проанализируем использование COM-объекта Scripting.FileSystemObject. Этот объект является частью Windows и отлично взаимодействует с 1С 7.7.
Рассмотрим пример реализации:
// Создаем объект для работы с файловой системой
FSO = СоздатьОбъект("Scripting.FileSystemObject");
Папка = FSO.GetFolder("Y:\MyData\");
КоллекцияФайлов = Папка.Files;
// Перебираем файлы в коллекции
// В 1С 7.7 для перебора коллекций COM используется объект "Enumeration"
Перечислитель = СоздатьОбъект("Enumeration");
Перечислитель.УстановитьОбъект(КоллекцияФайлов);
Пока Перечислитель.AtEnd() = 0 Цикл
ТекущийФайл = Перечислитель.Item();
// Свойство Name возвращается в корректной кодировке
Сообщить("Файл: " + ТекущийФайл.Name);
Перечислитель.MoveNext();
КонецЦикла;
Преимущество FSO заключается в том, что он работает напрямую с Windows API и возвращает строки, которые 1С автоматически конвертирует из Unicode в свою внутреннюю кодировку без потери кириллицы.
Если вам принципиально нужно использовать именно команду DIR (например, для сложной фильтрации или сортировки средствами ОС), мы можем заставить консоль выводить данные сразу в кодировке Windows-1251. Для этого перед основной командой нужно выполнить смену кодовой страницы с помощью CHCP 1251.
Проанализируем пример вызова:
// Используем связку команд через "&&"
// CHCP 1251 устанавливает кодировку ANSI для текущей сессии
// > nul подавляет вывод подтверждения смены кодовой страницы
Команда = "cmd /c chcp 1251 > nul && dir ""C:\Моя Папка\*.txt"" /b > ""C:\files.txt""";
КомандаСистемы(Команда);
// Теперь файл можно открывать стандартно
Тек = СоздатьОбъект("Текст");
Тек.Открыть("C:\files.txt");
Важно помнить, что пути к файлам в команде DIR лучше заключать в двойные кавычки, чтобы избежать ошибок при наличии пробелов в названиях папок.
В ситуациях, когда файл в кодировке OEM (CP866) уже создан сторонним приложением, и вы не можете на это повлиять, нам поможет объект ADODB.Stream. Он позволяет прочитать файл в любой кодировке и автоматически преобразовать его в текст, понятный для 1С.
Разберем, как это реализовать:
Stream = СоздатьОбъект("ADODB.Stream");
Stream.Type = 2; // Текстовый формат
Stream.Charset = "cp866"; // Указываем исходную кодировку файла
Stream.Open();
Stream.LoadFromFile("y:\files.txt");
// Читаем все содержимое сразу в переменную 1С
ВесьТекст = Stream.ReadText();
Stream.Close();
// Теперь переменная "ВесьТекст" содержит правильную кириллицу
// Можно разобрать её построчно или использовать дальше
Поскольку вы работаете на Windows Server 2008 R2, в вашем распоряжении есть мощный инструмент PowerShell. Если стандартные методы не подходят, можно вызвать команду PowerShell, которая сформирует список файлов сразу в нужной кодировке (например, в UTF-8 с BOM, который 1С 7.7 в некоторых случаях понимает лучше, или сразу в ANSI).
Пример команды для КомандаСистемы:
powershell -Command "Get-ChildItem -Path 'C:\Folder' -Filter *.txt | Select-Object -ExpandProperty Name | Out-File -FilePath 'C:\files.txt' -Encoding Default"
Параметр -Encoding Default в PowerShell соответствует системной кодировке ANSI (Windows-1251 для русской локализации), что обеспечит идеальную совместимость с 1С.
Подведем итоги нашего анализа:
НайтиПервыйФайл() и НайтиСледующийФайл(). Это быстро, надежно и не требует внешних вызовов.Scripting.FileSystemObject через COM-соединение.ADODB.Stream для корректной перекодировки из CP866 в Windows-1251.DIR командой CHCP 1251.Выбор конкретного метода зависит от ваших задач, но теперь вы знаете, как победить проблему кодировок раз и навсегда.