В работе с 1С:Предприятие часто возникает вопрос: где физически или логически хранится то или иное значение? Ответ зависит от типа данных — это могут быть константы, справочники, регистры сведений или даже временные таблицы в оперативной памяти. Понимание механизмов хранения критично для администраторов, разработчиков и опытных пользователей, так как влияет на резервное копирование, восстановление данных и оптимизацию производительности.
Неправильное обращение с хранилищами значений может привести к потере данных при обновлении платформы, сбоях транзакций или некорректной работе отчетов. Например, изменение константы напрямую в базе без фиксации транзакции не сохранит значение, а ошибка в коде, работающем с регистром накопления, способна исказить исторические данные. Эта статья поможет разобраться, где и как хранятся значения в разных объектах 1С, как их правильно обновлять и где искать в случае проблем.
Мы рассмотрим не только стандартные механизмы платформы 1С:Предприятие 8.3, но и типичные ошибки, которые допускают пользователи при работе с хранилищами. Особое внимание уделим тому, как значения сохраняются в разных режимах — от файлового варианта до клиент-серверного, а также нюансам работы с распределенными базами.
1. Типы хранилищ значений в 1С: где что лежит
Платформа 1С:Предприятие предлагает несколько механизмов для хранения данных, каждый из которых предназначен для своих целей. Основные типы хранилищ и их назначение:
📌 Константы — хранят глобальные настройки системы (например, ТекущаяДатаСеанса или ОсновнаяОрганизация). Их значения фиксированы для всей базы и изменяются редко. Физически константы хранятся в таблице _Const (для SQL-варианта) или в файле базы (для файлового варианта).
📊 Справочники — используются для хранения списков однотипных объектов (номенклатура, контрагенты, сотрудники). Данные хранятся в таблицах с префиксом _Reference (например, _Reference123 для справочника с идентификатором 123). Каждый элемент справочника имеет уникальный идентификатор и может содержать реквизиты (дополнительные поля).
📈 Регистры сведений — предназначены для хранения информации, которая изменяется во времени (курсы валют, цены номенклатуры, остатки на складах). Данные хранятся в таблицах с префиксом _InfoRg (например, _InfoRg1234). Регистры поддерживают версии данных, что позволяет отслеживать историю изменений.
📉 Регистры накопления — аналогичны регистрам сведений, но оптимизированы для учета количественных показателей (остатки товаров, взаимозачеты). Хранятся в таблицах _AccumRg. Особенность: поддерживают механизм итогов, который ускоряет выборку данных.
🖥️ Документы — хранят информацию о хозяйственных операциях (поступление товара, реализация, платежные поручения). Данные документов хранятся в таблицах _Document, а движения по регистрам — в отдельных таблицах (например, _Document123_Journals).
🔄 Временные таблицы — создаются в оперативной памяти на время сеанса (например, для промежуточных расчетов в отчетах). Не сохраняются в базе данных и исчезают после завершения сеанса.
⚠️ Внимание: В распределенных базах (с синхронизацией) часть данных может храниться в узлах обмена, а не в основной базе. При восстановлении из резервной копии важно учитывать все узлы, иначе возможна потеря актуальных данных.
2. Где физически хранятся значения в разных вариантах 1С
Место хранения данных зависит от варианта работы 1С:Предприятия. Рассмотрим основные сценарии:
💾 Файловый вариант — вся база хранится в одном файле с расширением .1CD (для платформы 8.3). Внутри этого файла данные организованы в виде таблиц, но доступ к ним возможен только через механизмы 1С. Физически файл представляет собой бинарную структуру, аналогичную базе данных SQLite.
🗄️ Клиент-серверный вариант (SQL) — данные хранятся в СУБД (Microsoft SQL Server, PostgreSQL, IBM DB2 или Oracle). Каждый объект метаданных (справочник, документ, регистр) представлен одной или несколькими таблицами. Например:
- 📋 Справочник "Номенклатура" → таблица
_Reference123(где 123 — идентификатор справочника) - 📄 Документ "ПоступлениеТоваров" → таблица
_Document456+ таблицы движений_Document456_Journals - ⚙️ Константы → таблица
_Const
☁️ Облачный вариант (1С:Фреш) — данные хранятся на серверах 1С в защищенном дата-центре. Пользователь не имеет прямого доступа к файлам или таблицам базы данных. Все операции выполняются через веб-интерфейс или тонкий клиент.
🔗 Распределенная база — данные хранятся в нескольких узлах, синхронизирующихся между собой. Каждый узел может иметь свою копию базы (файловую или SQL). Изменения передаются через механизм обмена данными.
| Вариант работы | Физическое хранение | Доступ к данным | Особенности |
|---|---|---|---|
| Файловый | Файл .1CD |
Только через 1С | Простота развертывания, ограниченная производительность |
| Клиент-серверный (SQL) | Таблицы в СУБД | Через 1С или SQL-запросы (с осторожностью!) | Высокая производительность, поддержка больших объемов данных |
| Облачный (1С:Фреш) | Серверы 1С | Только через веб-интерфейс | Автоматическое обновление, нет доступа к файлам базы |
| Распределенная база | Несколько файлов или SQL-баз | Через 1С с учетом узлов | Сложность администрирования, риски рассинхронизации |
⚠️ Внимание: При работе с SQL-вариантом никогда не редактируйте таблицы базы данных напрямую (например, через SQL Server Management Studio). Это может нарушить целостность данных и привести к ошибкам в работе 1С. Все изменения должны выполняться через механизмы платформы.
3. Как сохранить значение в 1С: механизмы и нюансы
Сохранение значений в 1С зависит от типа объекта. Рассмотрим основные сценарии:
🔧 Сохранение константы — выполняется через метод УстановитьЗначение() или в интерактивном режиме (меню Операции → Константы). Пример кода:
Константы.ТекущаяДатаСеанса.УстановитьЗначение(ТекущаяДата());
Изменение константы вступает в силу сразу для всех пользователей, но требует прав на редактирование.
📝 Сохранение элемента справочника — можно сделать через форму элемента или программно:
НовыйЭлемент = Справочники.Номенклатура.СоздатьЭлемент();
НовыйЭлемент.Наименование = "Ноутбук Dell XPS 13";
НовыйЭлемент.Артикул = "XPS-13-9320";
НовыйЭлемент.Записать();
Важно: после вызова Записать() изменения фиксируются в базе. Для отмены используется ОтменитьПроводку() (если элемент проводимый).
📊 Запись в регистр сведений — выполняется через менеджер регистра:
НаборЗаписей = РегистрыСведений.КурсыВалют.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Валюта.Установить(Справочники.Валюты.НайтиПоНаименованию("Доллар США"));
НаборЗаписей.Прочитать();
Если Не НаборЗаписей.Количество() = 0 Тогда
Запись = НаборЗаписей[0];
Запись.Курс = 92.50;
Запись.Записать();
КонецЕсли;
📄 Проводка документа — документы не только сохраняют свои данные, но и формируют движения по регистрам. Пример:
Док = Документы.ПоступлениеТоваров.СоздатьДокумент();
Док.Контрагент = Справочники.Контрагенты.НайтиПоНаименованию("ООО Ромашка");
Док.Записать();
Док.Провести(); // Формирует движения по регистрам
🔄 Транзакции — для группировки операций и обеспечения целостности данных используйте транзакции:
НачатьТранзакцию();
Попытка
// Код изменения данных
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
Сообщить("Ошибка сохранения: " + ОписаниеОшибки());
КонецПопытки;
☑️ Проверка перед сохранением данных
4. Где искать сохраненные значения: инструменты и методы
Если значение сохранено, но не отображается или потерялось, его можно найти несколькими способами:
🔍 Поиск через интерфейс 1С:
- 📌 Для констант:
Операции → Константы - 📋 Для справочников:
Операции → Справочники → [Имя справочника] - 📄 Для документов:
Операции → Журналы документов → [Имя журнала] - 📊 Для регистров:
Операции → Регистры → [Тип регистра]
🛠️ Поиск через запросы — универсальный метод для SQL-варианта. Пример запроса для поиска константы:
ВЫБРАТЬ
Значение КАК ЗначениеКонстанты
ИЗ
РегистрСведений.Константы КАК Константы
ГДЕ
Константы.Константа = &Константа
Для справочников можно использовать запрос:
ВЫБРАТЬ
Ссылка КАК Ссылка,
Наименование КАК Наименование
ИЗ
Справочник.Номенклатура КАК Номенклатура
ГДЕ
Номенклатура.Артикул = &Артикул
🗃️ Просмотр таблиц SQL (только для опытных пользователей!):
- 🔎 Для констант: таблица
_Const, полеValue - 📂 Для справочников: таблица
_Reference{ID}, поляDescr(наименование),Ref(ссылка) - 📑 Для документов: таблица
_Document{ID}, полеDocKind(вид документа)
🔗 Журнал регистрации — полезен для отслеживания, кто и когда изменил значение. Путь: Администрирование → Журнал регистрации. Здесь можно фильтровать события по типу (например, "Изменение константы").
💡 Консоль запросов (для разработчиков) — позволяет выполнять произвольные запросы к базе. Открывается через Сервис → Консоль запросов (в конфигураторе).
⚠️ Внимание: При работе с SQL-запросами к базе 1С избегайте операцийUPDATE,DELETEилиINSERTбез транзакций. Неправильные запросы могут нарушить ссылки между объектами и привести к ошибкам типа "Не найден объект базы данных".
Если значение "исчезло" после обновления конфигурации, проверьте журнал обновлений (Администрирование → Обновление конфигурации → Журнал). Возможно, объект был удален или изменен в новой версии.
5. Типичные ошибки при сохранении значений и как их избежать
Даже опытные пользователи и разработчики допускают ошибки при работе с хранилищами значений. Рассмотрим наиболее распространенные:
🚫 Игнорирование транзакций — изменение нескольких связанных объектов без транзакции может привести к частичному сохранению данных. Например, если при проводке документа произойдет сбой после записи самого документа, но до записи движений по регистрам, база окажется в неконсистентном состоянии.
🔄 Неправильная работа с версиями регистров — при записи в регистр сведений с поддержкой версий важно указывать период действия записи. Ошибка:
// Неверно: не указан период
Запись.Курс = 92.50;
Запись.Записать();
// Правильно:
Запись.Период = ТекущаяДата();
Запись.Курс = 92.50;
Запись.Записать();
📝 Прямое изменение реквизитов без метода Записать() — часто пользователи меняют значения в форме, но забывают сохранить:
Элемент.Наименование = "Новое название";
// Забыли вызвать Элемент.Записать()!
В этом случае изменения не попадут в базу.
🔍 Поиск по неиндексированным полям — медленные запросы к справочникам или регистрам без индексов могут блокировать базу. Например, поиск по произвольному реквизиту без отбора:
// Неверно: сканирует всю таблицу
ВЫБРАТЬ * ИЗ Справочник.Номенклатура ГДЕ Наименование ПОДОБНО "%ноутбук%"
// Правильно: использовать индексированное поле
ВЫБРАТЬ * ИЗ Справочник.Номенклатура ГДЕ Артикул = &Артикул
🗑️ Удаление объектов без проверки ссылочной целостности — удаление элемента справочника, на который есть ссылки в документах, приведет к ошибкам. Всегда проверяйте ссылки перед удалением:
Если НЕ Справочники.Номенклатура.Элемент123.СсылкаЗаполнена() Тогда
Справочники.Номенклатура.Элемент123.Удалить();
КонецЕсли;
🔄 Несинхронизированные изменения в распределенных базах — если изменить значение в одном узле и не дождаться синхронизации, другие узлы останутся с устаревшими данными. Всегда проверяйте статус обмена:
Если Не ОбменДанными.ПолученаЛиПоследняяВыгрузка() Тогда
Сообщить("Ожидание синхронизации...");
КонецЕсли;
Что будет, если прервать транзакцию?
Если транзакция не зафиксирована (например, из-за ошибки или принудительного завершения сеанса), все изменения внутри нее откатываются. Однако, если транзакция уже частично применена (например, документ записан, но движения нет), может потребоваться ручное восстановление целостности через тестирование и исправление базы (Администрирование → Тестирование и исправление).
6. Резервное копирование и восстановление значений
Чтобы избежать потери данных, необходимо регулярно создавать резервные копии. Рассмотрим основные методы:
💾 Резервное копирование файловой базы — выполняется через конфигуратор:
- Открыть базу в режиме конфигуратора.
- Выбрать
Администрирование → Выгрузить информационную базу. - Указать путь для сохранения файла
.dt. - Для автоматического резервирования использовать планировщик задач Windows или скрипты.
🗄️ Резервное копирование SQL-базы — зависит от СУБД:
- 🖥️ Для Microsoft SQL Server: использовать
SQL Server Management Studioили командуBACKUP DATABASE. - 🐧 Для PostgreSQL: команда
pg_dump.
Пример скрипта для MS SQL:
BACKUP DATABASE [YourDatabaseName]
TO DISK = 'C:\Backups\YourDatabaseName.bak'
WITH INIT, NAME = 'Full Backup of YourDatabaseName';
☁️ Облачные резервные копии — для 1С:Фреш резервирование выполняется автоматически. Пользователь может создать точку восстановления вручную через личный кабинет.
🔄 Восстановление из резервной копии:
- 💾 Для файловой базы:
Администрирование → Загрузить информационную базу. - 🗄️ Для SQL-базы: использовать
RESTORE DATABASE(предварительно остановив службу 1С:Предприятия).
📋 Экспорт/импорт данных — если нужно восстановить только часть данных (например, справочник), используйте механизмы обмена:
// Экспорт в XML
ОбменДанными.ЗаписатьXML(ИмяФайла, Справочники.Номенклатура);
// Импорт из XML
ОбменДанными.ПрочитатьXML(ИмяФайла);
⚠️ Внимание: При восстановлении базы из резервной копии все изменения, сделанные после создания копии, будут утеряны. Всегда проверяйте дату резервной копии перед восстановлением. Для критичных систем используйте дифференциальное резервирование (например, ежедневные инкрементальные копии + еженедельные полные).
Регулярное резервное копирование — единственный способ гарантированно защитить данные от потери. Даже если значение "исчезло" из-за ошибки пользователя или сбоя, его можно будет восстановить из бэкапа.
7. Работа с значениями в распределенных базах
Распределенные базы 1С используются для синхронизации данных между несколькими узлами (например, центральный офис и филиалы). Здесь есть свои нюансы хранения и сохранения значений:
🔗 Механизм обмена данными — изменения в одном узле передаются в другие через планы обмена. Каждый узел имеет свою копию базы, но некоторые данные могут быть общими (синхронизируемыми), а другие — локальными (только для текущего узла).
📡 Типы узлов:
- 🏢 Центральный узел — обычно содержит полную копию данных.
- 🏠 Периферийный узел — может хранить только часть данных (например, только свои документы).
- 🔄 Автономный узел — работает offline и синхронизируется при подключении.
📤 Выгрузка и загрузка данных — обмен происходит в два этапа:
- Выгрузка изменений из источника в файл (формат
.cfили.xml). - Загрузка изменений в целевой узел.
Пример кода для принудительной выгрузки:
ОбменДанными.ВыгрузитьДанные(ПланОбмена.Основной, Истина);
⚠️ Конфликты при обмене — если одно и то же значение изменили в двух узлах, возникает конфликт. Разрешение конфликтов настраивается в плане обмена. Варианты:
- 🔄 Приоритет центрального узла — изменения из центра перезаписывают периферийные.
- ⏱️ Приоритет по времени — сохраняется самое позднее изменение.
- ❌ Ручное разрешение — пользователь выбирает, какое значение сохранить.
📊 Проверка статуса обмена — чтобы убедиться, что значения дошли до всех узлов, используйте отчеты по обмену:
Отчет = Отчеты.ВедомостьПоОбменуДанными.Создать();
Отчет.ПланОбмена = ПланыОбмена.Основной;
Отчет.Сформировать();
⚠️ Внимание: В распределенных базах никогда не изменяйте идентификаторы объектов (ссылки) вручную. Это приведет к рассинхронизации узлов. Если объект нужно "перенести" между узлами, используйте механизмы обмена, а не прямое копирование.
8. Программное управление значениями: советы разработчикам
Для разработчиков, работающих с 1С, важно не только знать, где хранятся значения, но и как с ними эффективно работать на уровне кода.
🔧 Оптимизация запросов — избегайте выборки всех полей, если нужны только некоторые:
// Неверно: выбирает все поля
ВЫБРАТЬ * ИЗ Справочник.Номенклатура
// Правильно: только нужные поля
ВЫБРАТЬ
Ссылка,
Наименование,
Артикул
ИЗ
Справочник.Номенклатура
📈 Использование временных таблиц — для сложных расчетов создавайте временные таблицы, чтобы не нагружать основную базу:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Товар КАК Товар,
| СУММА(Количество) КАК Итого
|ПОМЕСТИТЬ ВТ_ИтогиПоТоварам
|ИЗ
| Документ.РеализацияТоваров.Товары
|СГРУППИРОВАТЬ ПО
| Товар";
Запрос.Выполнить();
🔄 Контроль транзакций — всегда проверяйте результат фиксации:
НачатьТранзакцию();
Попытка
// Изменение данных
Если Не ЗафиксироватьТранзакцию() Тогда
Сообщить("Ошибка фиксации транзакции!");
КонецЕсли;
Исключение
ОтменитьТранзакцию();
Сообщить("Транзакция отменена: " + ОписаниеОшибки());
КонецПопытки;
🛡️ Блокировки данных — для предотвращения конфликтов при параллельной работе используйте блокировки:
Элемент = Справочники.Номенклатура.НайтиПоНаименованию("Ноутбук");
Элемент.Заблокировать();
Попытка
Элемент.Цена = 50000;
Элемент.Записать();
КонецПопытки;
Элемент.Разблокировать();
📡 Работа с кэшем — для ускорения доступа к часто используемым данным используйте кэширование:
Процедура ПолучитьНоменклатуруПоАртикулу(Артикул)
Если Кэш.НоменклатураПоАртикулу = Неопределено Тогда
Кэш.НоменклатураПоАртикулу = Новый Соответствие;
КонецЕсли;
Если Кэш.НоменклатураПоАртикулу.СодержитКлюч(Артикул) Тогда
Возврат Кэш.НоменклатураПоАртикулу[Артикул];
Иначе
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ ПЕРВЫЕ 1 Ссылка ИЗ Справочник.Номенклатура ГДЕ Артикул = &Артикул";
Запрос.УстановитьПараметр("Артикул", Артикул);
Результат = Запрос.Выполнить().Выгрузить();
Если Результат.Количество() > 0 Тогда
Кэш.НоменклатураПоАртикулу.Вставить(Артикул, Результат[0].Ссылка);
Возврат Результат[0].Ссылка;
КонецЕсли;
КонецЕсли;
Возврат Неопределено;
КонецПроцедуры
⚠️ Внимание: При работе с большими объемами данных избегайте длительных транзакций. Они блокируют таблицы и могут привести к тайм-аутам. Разбивайте операции на небольшие пакеты (например, по 1000 записей) и фиксируйте их отдельно.
Для критичных операций (например, массового изменения цен) всегда пишите код с обработкой ошибок и откатными механизмами. Это позволит избежать потери данных при сбоях.
FAQ: Частые вопросы о хранении значений в 1С
Как найти, в какой таблице SQL хранится справочник "Контрагенты"?
Идентификатор таблицы для справочника можно узнать через конфигуратор:
- Откройте конфигурацию в режиме редактирования.
- Найдите справочник "Контрагенты" в дереве объектов.
- В панели свойств посмотрите поле
Идентификатор(например,Reference15). - В SQL-базе данные будут храниться в таблице
_Reference15.
Для удобства можно использовать запрос к системной таблице _1SCatalog, где хранятся соответствия объектов и таблиц.
Почему после изменения константы в одном сеансе другие пользователи её не видят?
Это связано с механизмом кэширования констант. По умолчанию константы кэшируются на уровне сеанса и обновляются раз в 5 минут (настройка КэшированиеКонстант в параметрах информационной базы). Чтобы изменения вступили в силу сразу:
- Используйте метод
ОчиститьКэшКонстант()(требуются права администратора). - Перезапустите сеансы пользователей.
- В коде после изменения константы вызовите
ОбновитьКэшКонстант().