В процессе разработки часто возникает задача сохранения файлов (отчетов, выгрузок, документов) в стандартные папки пользователя Windows. Основная сложность заключается в том, что на одном компьютере могут работать несколько сотрудников под разными учетными записями операционной системы. Пути к их папкам «Документы» будут различаться, например: C:\Users\Ivanov\Documents и C:\Users\Petrov\Documents. Ситуация усложняется, если пользователи работают в одной информационной базе 1С под одним и тем же логином, но при этом используют разные системные профили Windows.
В данной статье мы разберем несколько способов решения этой задачи, проанализируем их преимущества и недостатки, а также выясним, какой метод является наиболее надежным и современным.
Начнем с самого простого и эффективного метода, который предоставляет сама платформа 1С. Функция КаталогДокументов() предназначена специально для получения пути к системной папке документов текущего пользователя. Это наиболее «чистый» способ с точки зрения программирования в 1С, так как он не требует обращения к внешним библиотекам или компонентам.
Рассмотрим пример кода:
ПутьКДокументам = КаталогДокументов();
ИмяФайла = ПутьКДокументам + "ОтчетПродаж.xlsx";
Результат.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.XLSX);
Преимущества этого метода:
C: на D:), функция КаталогДокументов() вернет актуальный путь, в то время как жестко прописанные пути или простые склейки строк выдадут ошибку.Иногда возникают ситуации, когда нужно получить доступ не только к документам, но и к корню профиля пользователя или другим специфическим папкам. В Windows существуют переменные окружения, такие как %USERPROFILE%. Мы можем обратиться к ним через COM-объект WScript.Shell.
Проанализируем программную реализацию этого способа:
Shell = Новый COMОбъект("WScript.Shell");
ПутьПрофиля = Shell.ExpandEnvironmentStrings("%USERPROFILE%");
ПутьКДокументам = ПутьПрофиля + "\Documents";
Разберем подробнее, что здесь происходит. Метод ExpandEnvironmentStrings «раскрывает» системную переменную, превращая её в полный путь. Однако стоит учитывать критически важный нюанс: папка документов не всегда называется «Documents» внутри профиля, и она не всегда там находится. Например, в локализованных старых версиях Windows или при использовании облачных сервисов путь может отличаться.
Еще один вариант, который часто встречается в старых разработках — это попытка «собрать» путь вручную, узнав имя пользователя в системе. Для этого используется объект WScript.Network.
Пример реализации:
Network = Новый COMОбъект("WScript.Network");
ИмяПользователяОС = Network.UserName;
ПутьКДокументам = "C:\Users\" + ИмяПользователяОС + "\Documents";
Почему этот метод считается ненадежным? Выясним причину. Во-первых, имя пользователя в Windows (логин) не всегда совпадает с именем папки в C:\Users\. Во-вторых, этот метод полностью игнорирует возможность переноса папок пользователем. В-третьих, он привязан к структуре диска C:, которая может быть иной в терминальных сессиях или специфических серверных конфигурациях. Мы не рекомендуем использовать данный подход для определения путей к папкам.
При использовании любого из вышеперечисленных методов крайне важно понимать, в каком контексте выполняется код. Рассмотрим две ситуации:
КаталогДокументов() вернет путь к папке именно того человека, который сейчас сидит за монитором и работает в 1С. Это именно то, что требовалось автору задачи.КаталогДокументов() в серверной процедуре, система вернет путь к профилю того пользователя, под которым запущена служба 1C:Enterprise Server (часто это USR1CV8). В большинстве случаев серверный профиль не имеет доступа к личным папкам пользователей на их локальных машинах.Вывод: Если вам нужно сохранить файл в документы пользователя, всегда инициируйте получение пути и сохранение файла на стороне клиента. Для понимания нюансов взаимодействия между контекстами подойдёт руководство по работе с файлами в клиент-серверных управляемых формах.
Современные версии Windows 10 и 11 активно интегрируются с облачным хранилищем OneDrive. В таких системах реальный путь к папке «Документы» часто выглядит так: C:\Users\ИмяПользователя\OneDrive\Документы.
Если вы будете использовать "ручную" склейку пути (как в Методе 3), ваша программа не найдет папку и выдаст ошибку доступа. Использование встроенной функции КаталогДокументов() или метода ExpandEnvironmentStrings позволяет избежать этой проблемы, так как операционная система сама подскажет 1С актуальный перенаправленный путь.
Если вам требуется максимальная точность или доступ к папкам, которые не возвращаются стандартными функциями 1С, можно обратиться к реестру Windows. Пути ко всем пользовательским папкам хранятся в ветке:
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders
Проанализируем, как прочитать эти данные из 1С:
Shell = Новый COMОбъект("WScript.Shell");
Попытка
ПутьКДокументам = Shell.RegRead("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders\Personal");
// Personal — это системный идентификатор папки Мои документы
ПутьКДокументам = Shell.ExpandEnvironmentStrings(ПутьКДокументам);
Исключение
Сообщить("Не удалось прочитать путь из реестра");
КонецПопытки;
Этот способ является наиболее мощным, так как позволяет получить доступ к любой системной папке (Рабочий стол, Загрузки, Видео и т.д.), даже если они были глубоко кастомизированы администратором домена.
Подводя итог нашему разбору, выделим лучшие практики для разработчика 1С:
КаталогДокументов() — это быстро, надежно и не требует лишнего кода.WScript.Network, но не стройте на основе этого имени пути к файлам.КаталогВременныхФайлов(), чтобы не замусоривать личное пространство пользователя.Применяя эти знания, вы сможете создавать отказоустойчивые механизмы сохранения файлов, которые будут корректно работать у любого пользователя в любой конфигурации системы Windows.