Каждый разработчик на платформе 1С:Предприятие рано или поздно сталкивается с неприятной ситуацией: после многочасовой работы над сложным алгоритмом во внешней обработке (файлы .epf) или отчете (файлы .erf) происходит внезапное отключение электроэнергии, зависание компьютера или «вылет» Конфигуратора. В результате файл обработки повреждается, превращаясь в пустой файл размером 0 байт, либо откатывается к состоянию на начало рабочего дня. Стандартный Конфигуратор 1С, к сожалению, не имеет встроенного механизма версионирования и автоматического резервного копирования редактируемых внешних файлов.
В этой статье мы подробно разберем несколько эффективных способов решения этой проблемы — от простейших облачных сервисов до профессиональных инструментов контроля версий и автоматических скриптов, которые навсегда обезопасят ваш код от случайной потери.
Это самый простой и доступный способ, не требующий от программиста установки сложных сред разработки или написания кода. Суть метода заключается в том, что вы создаете рабочую папку для своих обработок внутри каталога, который синхронизируется с облачным сервисом.
Разберем, как это работает на примере популярных облаков:
Ctrl+S в Конфигураторе) локальный клиент облака отправляет новую версию файла на сервер. Если файл повредится или вы случайно удалите важный кусок кода, вам достаточно зайти в веб-интерфейс облака, кликнуть правой кнопкой мыши по файлу, выбрать пункт «История версий» (Version History) и восстановить любую предыдущую копию за последние 30 дней..epf-файла, созданные несколько минут или часов назад.Преимущества: Настройка занимает всего пару минут; работает в фоновом режиме; файлы дополнительно защищены от физической поломки жесткого диска вашего компьютера.
Недостатки: Требуется постоянное интернет-соединение для своевременной отправки изменений; нет возможности посмотреть точечную разницу в коде (diff) между версиями, так как файлы .epf являются бинарными.
Если вы хотите перейти на современный уровень разработки, настоятельно рекомендуем рассмотреть среду 1С:EDT, созданную на базе Eclipse. В отличие от классического Конфигуратора, здесь механизмы безопасности кода продуманы до мелочей.
Проанализируем основные защитные инструменты в EDT:
Если вам необходимо реализовать схему, при которой при каждом сохранении файла автоматически создается его архивная копия с суффиксом даты и времени (например, MyProcessing_20261024_153022.epf), можно использовать простой фоновый скрипт на операционной системе.
Рассмотрим пример реализации такого решения на языке Python с использованием библиотеки watchdog. Этот скрипт будет отслеживать изменения в вашей рабочей папке и автоматически копировать измененные файлы в архивную подпапку.
Разберем по шагам создание такого скрипта:
pip install watchdog.backup_watcher.py и вставьте в него следующий код:
import os
import time
import shutil
from datetime import datetime
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
# Путь к вашей рабочей папке с обработками 1С
WATCH_DIR = r"C:\1C_Develop\MyProcessings"
# Путь к папке, где будет храниться история версий
BACKUP_DIR = r"C:\1C_Develop\MyProcessings\_history"
class ProcessingBackupHandler(FileSystemEventHandler):
def on_modified(self, event):
# Отслеживаем только файлы обработок .epf и отчетов .erf
if event.is_directory:
return
file_ext = os.path.splitext(event.src_path)[1].lower()
if file_ext in ['.epf', '.erf']:
file_name = os.path.basename(event.src_path)
# Проверяем, что изменение не произошло в самой папке бэкапа
if BACKUP_DIR in event.src_path:
return
# Пауза, чтобы 1С успела монопольно записать и освободить файл
time.sleep(0.5)
# Формируем имя файла с временной меткой
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
base_name, ext = os.path.splitext(file_name)
backup_filename = f"{base_name}_{timestamp}{ext}"
# Создаем папку бэкапа, если она отсутствует
if not os.path.exists(BACKUP_DIR):
os.makedirs(BACKUP_DIR)
backup_path = os.path.join(BACKUP_DIR, backup_filename)
try:
shutil.copy2(event.src_path, backup_path)
print(f"[OK] Создана копия: {backup_filename}")
except Exception as e:
print(f"[Error] Не удалось скопировать {file_name}: {str(e)}")
if __name__ == "__main__":
event_handler = ProcessingBackupHandler()
observer = Observer()
observer.schedule(event_handler, path=WATCH_DIR, recursive=False)
observer.start()
print(f"Мониторинг папки {WATCH_DIR} запущен. Нажмите Ctrl+C для выхода.")
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
observer.join()
Запустите этот скрипт в фоне. Теперь при каждом сохранении файла в папке C:\1C_Develop\MyProcessings скрипт мгновенно создаст его копию в подпапке _history с указанием точного времени изменения. Вы никогда не потеряете ни одной строчки кода!
Для разработчиков, которые предпочитают оставаться в классическом Конфигураторе 1С, существуют утилиты, автоматизирующие рутинные процессы резервного копирования.
Ctrl+S.Для крупных проектов и профессиональной командной разработки стандартным решением является использование распределенной системы контроля версий Git. Однако хранить бинарные файлы .epf напрямую в Git не очень удобно: система не может отобразить изменения в коде, объединить разные версии (merge) или показать историю правок конкретной строки.
Чтобы решить эту проблему, разработчики используют инструменты декомпозиции обработок в текстовый формат:
.epf / .erf на составляющие элементы: XML-описания форм, файлы модулей на языке 1С (расширение .bsl) и макеты.pre-commit) процесс распаковки автоматизируется. Перед каждым коммитом утилита разбирает измененную обработку на исходные текстовые файлы.Если вы хотите решить задачу непосредственно внутри базы данных 1С, вы можете разработать небольшое расширение конфигурации, которое будет выступать в роли локального депозитария внешних обработок.
Выясним логику работы такого решения:
ХранилищеВнешнихОбработок.ХранилищеЗначения для записи двоичных данных файлов .epf/.erf, а также реквизиты Автор, ДатаСоздания и НомерВерсии.Пример кода на встроенном языке 1С для программного добавления новой версии файла в такое хранилище:
Процедура СохранитьНовуюВерсиюОбработки(ПутьКФайлу, ИмяОбработки) Экспорт
// Получаем текущую максимальную версию по имени обработки
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| МАКСИМУМ(ХранилищеОбработок.Версия) КАК МаксВерсия
|ИЗ
| Справочник.ХранилищеОбработок КАК ХранилищеОбработок
|ГДЕ
| ХранилищеОбработок.Наименование = &Наименование";
Запрос.УстановитьПараметр("Наименование", ИмяОбработки);
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
НоваяВерсия = 1;
Если Выборка.Следующий() И ЗначениеЗаполнено(Выборка.МаксВерсия) Тогда
НоваяВерсия = Выборка.МаксВерсия + 1;
КонецЕсли;
// Создаем новый элемент справочника для хранения файла
НоваяЗапись = Справочники.ХранилищеОбработок.СоздатьЭлемент();
НоваяЗапись.Наименование = ИмяОбработки;
НоваяЗапись.Версия = НоваяВерсия;
НоваяЗапись.ДатаСоздания = ТекущаяДата();
НоваяЗапись.Автор = Пользователи.ТекущийПользователь();
// Читаем двоичные данные файла обработки и помещаем в хранилище значений
ДвоичныеДанныеФайла = Новый ДвоичныеДанные(ПутьКФайлу);
НоваяЗапись.ФайлХранилище = Новый ХранилищеЗначения(ДвоичныеДанныеФайла, Новый СжатиеДанных(9));
НоваяЗапись.Записать();
Сообщить("Успешно сохранена версия " + НоваяВерсия + " для обработки " + ИмяОбработки);
КонецПроцедуры
Такой подход позволяет хранить всю историю изменения внешних обработок непосредственно внутри рабочей или тестовой базы 1С, обеспечивая быстрый доступ к любой архивной копии для всех разработчиков вашей компании. В качестве готового решения можно использовать инструмент для массовой загрузки и выгрузки обработок с контролем версий.