Кто менял данные, если все ходят под Администратором

29.09.26

База данных - Журнал регистрации

Документы в базе переписаны, а кто это сделал, непонятно: история версий пуста, в журнале регистрации во всех строках один «Администратор», а список обрывается на десяти тысячах записей. Разобрал все три стены, и ни одна не стоит там, где кажется. Лимит в 10 000 живет в форме БСП, а платформенный ВыгрузитьЖурналРегистрации за тот же период отдает 116 595 строк за 25 секунд. Номер сеанса без времени старта не значит ничего: за неделю номер 1 на одной машине стартовал 582 раза, и группировка по нему слепляет полтысячи разных сеансов в одну строку. А путь к запущенной внешней обработке в журнале лежит, просто не в том событии, где его обычно ищут. Внутри код, цифры с живой базы Бухгалтерии и разбор двух ловушек отбора, на которых легко сесть: опечатка в имени события не падает, а тихо отдает ноль, и без отбора по событиям две трети выборки оказываются мусором.

В базе Бухгалтерии за три месяца переписались документы. У части сменились номера, у части — реквизиты. Вопрос стоял простой: кто это сделал. Имени я тут не назову, база чужая. Разберем, чем на такой вопрос вообще отвечают, когда все три привычных источника молчат.

Дальше было три стены подряд.

История версий объекта пуста. Открываю документ, смотрю версии — ничего, как будто его никто не трогал.

Список в журнале обрывается. Дошел до десяти тысяч записей и кончился, а самое раннее изменение было явно раньше.

В журнале во всех строках одно имя: «Администратор». Личная учетная запись есть у каждого разработчика, но обработки запускают под общей, так удобнее. Кто именно сидел под ней в нужный день, журнал не говорит.

Ни одна из трех стен не оказалась тем, чем выглядела. Все цифры ниже сняты 29.09.2026 на живой базе Бухгалтерии 3.0.206, платформа 8.5.1.1343. Период берем с запасом, с 1 января по 29 сентября, если не сказано иное: сузить его всегда успеем, а пропущенное начало искать заново.

 

Пустая история версий — сама по себе улика

Про пустую историю версий первым делом думают, что версионирование выключено. Иногда так и есть: функциональную опцию «Использовать версионирование объектов» могли снять.

Но есть вариант интереснее, и он сразу сужает круг. Посмотрите в конфигураторе подписку на событие записи, общий модуль ВерсионированиеОбъектовСобытия. Обработчик начинается так:

// Безусловная проверка на ОбменДанными.Загрузка не требуется, т.к. в момент записи
// версионируемого объекта при обмене необходимо сохранить его текущую версию в истории версий.
Если Источник.ОбменДанными.Загрузка И Источник.ОбменДанными.Отправитель = Неопределено Тогда
	Возврат;
КонецЕсли;

Читается это так: если у объекта выставлен флаг загрузки, а отправитель не задан, версия не пишется вообще. Судя по коду, отправитель заполнен тогда, когда объект приехал из узла обмена; когда флаг выставили руками, чтобы объект записался в обход проверок заполнения, отправителя нет, и подписка выходит на первой же строке.

Если отправитель задан, дело доходит до модуля ВерсионированиеОбъектов, и там стоит второй выход, до вызова, который создает версию:

Если Источник.ОбменДанными.Загрузка Тогда
	Если Не Источник.Ссылка.Пустая() Тогда
		ЗаписатьДанныеТекущейВерсии(Источник.Ссылка, Истина);
	КонецЕсли;
	Возврат;
КонецЕсли;

Имя ЗаписатьДанныеТекущейВерсии обманчиво: новой строки в регистр она не добавляет. Внутри берется НомерПоследнейВерсии без увеличения, набор по этому номеру читается, и содержимое дописывается только туда, где оно пустое. То есть новой записи в истории версий не появляется ни на одном из двух путей.

Если версионирование включено, а у документа, который явно менялся, история версий пуста, его писали с ОбменДанными.Загрузка = Истина: либо обменом, либо кодом, который этот флаг выставил. Сначала все-таки проверьте функциональную опцию: это одна строка, и она снимает половину догадок.

А вот журнал регистрации этот флаг не глушит. Я записал элемент справочника с выставленным флагом и сразу прочитал журнал:

НовыйЭлемент = Справочники.Контрагенты.СоздатьЭлемент();
НовыйЭлемент.Наименование = "Проба журнала";
НовыйЭлемент.ОбменДанными.Загрузка = Истина;
НовыйЭлемент.Записать();

Запись в журнале появилась: «Данные. Добавление · Справочник.Контрагенты · Проба журнала». Опыт поставлен на элементе справочника, не на документе, но флаг и подписка тут общие. То есть история версий молчит, а журнал помнит. Значит, копать надо там.

 

Ограничение в 10 000 записей — не платформенное

Список обрывался не из-за платформы. Откройте в конфигураторе обработку ЖурналРегистрации из Библиотеки стандартных подсистем, модуль формы. Там есть переменная КоличествоПоказываемыхСобытий, в поставке Бухгалтерии 3.0.206 по умолчанию 200, а десять тысяч — это максимум в списке выбора, причем для веб-клиента его еще и режут до тысячи. Ограничение живет в форме, а не в движке.

Платформенный метод ВыгрузитьЖурналРегистрации количество записей вообще не требует. Параметр есть, но он необязательный, и если его не передавать, читается весь период целиком.

Проверка на той же базе, один и тот же отбор, разница только в последнем параметре:

Вызов Строк вернулось
ВыгрузитьЖурналРегистрации(Таблица, Отбор) 116 595
ВыгрузитьЖурналРегистрации(Таблица, Отбор, , , 10000) ровно 10 000

 

Чтение всего периода заняло 25,3 секунды на журнале в 349 166 записей. Если журнал у вас на порядок больше, режьте период: время растет вместе с числом прочитанных строк.

 

Номер сеанса без времени старта ничего не значит

Третья стена — общая учетная запись. Тут журнал дает две зацепки: колонку Компьютер (она заполняется именем машины) и колонку Сеанс. Казалось бы, группируй записи по паре «номер сеанса и компьютер», и разные люди разойдутся по разным строкам.

Так мы и сделали. И получили ерунду: в строке «сеанс 1» оказалось больше тысячи изменений, а в колонке «Приложение» стоял толстый клиент, хотя работа шла в тонком.

Причина в том, что номера сеансов повторяются. Замер ниже показывает это прямо; из него же видно, что номер держится за сеансом, пока тот жив, а после закрытия уходит следующему. За всю историю базы номер ничего не опознает.

Масштаб видно по событиям старта сеанса за одну неделю:

  Значение
стартов сеансов всего 2 503
различных пар «номер и компьютер» 317
сколько раз стартовала пара «номер 1 и эта машина» 582

 

Пятьсот восемьдесят два разных сеанса под одним номером за семь дней, с 22.09.2026 по 29.09.2026. Группировка по номеру складывала их в одну строку, перемешивая работу разных людей и фоновых заданий.

Прикиньте заодно свою: сколько раз за неделю перезапускается клиент, умножьте на число разработчиков. Много выйдет?

Лечится это просто, если знать. У платформы есть событие _$Session$_.Start, которое пишется в журнал при каждом старте сеанса. Читаем его вместе с изменениями данных, сортируем выборку по дате и при проходе запоминаем для каждой пары «номер и компьютер» момент последнего старта. Этот момент становится третьей частью ключа.

Эффект видно на выборке изменений данных за ту же неделю: группировка по паре дает 114 строк, группировка по тройке — 616. Пятьсот два реальных сеанса до этого прятались в чужих строках, и как раз в одной из них терялся документ, который мы искали.

 

Колонка «Компьютер»

Вот теперь работает и вторая зацепка. Под общей учетной записью именно имя машины отличает одного разработчика от другого. У фоновых заданий эта колонка на проверочной базе за весь период не была заполнена ни разу.

 

Чем именно правили: путь к обработке в журнале есть

Дальше казалось, что мы уперлись окончательно. Понятно, с какой машины и в какие минуты шла правка. А чем именно правили, журнал знать не может: обработка внешняя, а какая — нигде не записано.

Оказалось, может: искали не в том событии ))

Событие _$Session$_.Start про запущенную обработку не знает ничего: поля Данные и ПредставлениеДанных у него пустые. А есть отдельное событие _$Session$_.ExternalDataProcessorConnect, по-русски «Сеанс. Подключение внешней обработки». И вот у него в поле Данные лежит структура из шести ключей:

Путь                    = D:\Обработки\ПеренумерацияДокументов.epf
Имя                     =
БезопасныйРежим         = Нет
ПрофильБезопасности     =
ЗащитаОтОпасныхДействий = Да
КодЯзыка                =

Полный путь к файлу, вместе с каталогом. Каталог обычно и выдает, чей это файл и откуда его принесли. Видно это и в типовой форме журнала, если задать отбор по событию, — снимок выше снят именно там.

Достается путь так:

Если ТипЗнч(Запись.Данные) = Тип("Структура")
	И Запись.Данные.Свойство("Путь") Тогда
	Путь = СокрЛП(Строка(Запись.Данные.Путь));
КонецЕсли;

Что тип именно Структура, а не фиксированная, проверено отдельно 29.09.2026 двумя путями: на платформе и через внешнее соединение. Имя ключа можно не угадывать: в Библиотеке стандартных подсистем, общий модуль ЖурналРегистрации, прямо под комментарием с именем этого события перечислены «Путь» и «Код языка».

Дальше остается сложить одно с другим: взять записи о подключении обработок и записи об изменении данных, разложить по сеансам одним и тем же ключом и выстроить по времени. Получается лента вида «в 14:07 сеанс подключил такой-то файл, с 14:07 по 14:12 переписал такие-то документы».

Оговорка, куда же без нее )) Журнал хранит путь к файлу, но не то, что обработка делала. Связь «запустил обработку — переписал документы» выводится из совпадения сеанса и времени, сам журнал ее не подтверждает. Если в одном сеансе запустили две обработки и что-то поправили руками, все три факта встанут рядом, и какой из них чей, придется решать самому.

 

Две ловушки в отборе, на которых легко сесть

Первая: неизвестное имя события платформа не отвергает. Я был уверен в обратном и даже построил на этом код: перебирал имена событий по одному внутри Попытка, рассчитывая, что неподдерживаемое имя даст исключение. Не дает.

Опыт поставлен на отдельной проверочной базе с коротким журналом, поэтому числа тут на три порядка меньше остальных в статье и с ними не сравниваются. Важно не их значение, а то, что исключения нет ни в одной строке.

Что передано в отбор «Событие» Строк вернулось
_$Data$_.Update 5
_$Data$_.ТакогоИмениНет 0
мусор 0
пустая строка 0

 

Ни одно из проверенных имен исключения не дало: на незнакомое имя просто приходит пустая выборка. Это значит, что опечатка в имени события не падает, а тихо превращается в «за период ничего не было». Имена лучше не набирать по памяти: пять имен событий изменения данных лежат литералами в типовой Бухгалтерии, общий модуль ОбработкаНовостейКлиент.

Вторая: без отбора по событиям журнал отдает всё подряд. Кажется, что можно прочитать целиком и разобраться потом. За тот же период приезжает столько:

Отбор Строк
только изменения данных 116 595
без отбора по событиям 349 166

 

Из этих 349 166 почти половина — начала и фиксации транзакций, их 168 507. Еще 24 852 — смены области данных, 6 086 — входы в систему. Изменения данных составляют треть, 33,4 процента. Если не отфильтровать, в отчет о том, кто правил документы, попадут чужие входы в систему и служебные метки, и выглядеть они будут убедительно.

 

Как отличить документ от служебной записи

Еще одна мелочь, без которой разбор тонет. Изменений данных в журнале много, но подавляющее большинство из них — записи регистров: замеры статистики, серверные оповещения, данные монитора показателей. Документов среди них единицы, а ищут обычно именно документы.

Отличаются они по двум полям сразу. В колонке Метаданные лежит полное имя объекта, и у документа оно начинается с Документ. — например, Документ.СчетФактураВыданный. А колонка ПредставлениеДанных у документа заполнена и содержит его читаемое представление вида «Реализация (акт, накладная, УПД) 0000-000602 от 29.12.2016». У записи регистра она либо пустая, либо содержит одно голое число вроде «155».

ЭтоДокумент = СтрНачинаетсяС(Строка(Запись.Метаданные), "Документ.")
	И Не ПустаяСтрока(Строка(Запись.ПредставлениеДанных));

Обе проверки нужны именно вместе. Одного «представление непустое» мало: у регистра там может стоять то самое «155», и он пролезет в отбор. Одного Документ. в метаданных тоже мало: так в выборку попадут записи без читаемого представления, и в колонке будет пусто.

Из этого получается отдельная колонка «какие документы записаны в этом сеансе». Вместо тысячи строк про регистры в ней видно две строки про документы, которые и надо было найти.

Попутно: описание объекта лучше склеивать из представления метаданных и представления данных. Из одного представления данных у регистров выйдет голое «155», по которому ничего не понять.

 

Что собралось: обработка и два урока

Чтобы не собирать эту логику заново при каждом разборе, мы свели ее в небольшую обработку. Она читает журнал за период без ограничения по количеству, режет по стартам сеансов, показывает по каждому сеансу компьютер, время, число изменений, записанные документы и путь к запущенной внешней обработке. Двойной клик по строке разворачивает ленту по минутам.

В базу она ничего не пишет, и это проверено, а не обещано: в коде нет ни одного вызова записи; журнал за окно ее работы содержит только служебные регистры БСП, которые пишутся при входе в программу; и она отработала штатно под активной общей датой запрета изменения, а сама дата запрета в том же сеансе отклоняла запись документа.

Но обработка тут дело десятое. Больше всего времени забрали две вещи, про которые достаточно было знать заранее: что лимит в десять тысяч снимается одним неуказанным параметром и что номер сеанса без времени старта не опознает ничего. В журнале лежит больше, чем типовая форма показывает по умолчанию. Достать это из нее можно: поставьте отбор по событию «Сеанс. Подключение внешней обработки», и путь будет виден прямо в колонке «Сведения о событии». Чего форма не делает — не сводит запуски обработок с изменениями данных по сеансам и не разбирается с повторяющимися номерами. Ради этого и пришлось обходить ее стороной.

Вступайте в нашу телеграмм-группу Инфостарт

журнал регистрации ВыгрузитьЖурналРегистрации ExternalDataProcessorConnect подключение внешней обработки путь к внешней обработке история версий пуста ОбменДанными.Загрузка версионирование объектов кто изменил документ кто менял данные общая учетная запись работа под Администратором номер сеанса лимит 10000 записей отбор по событиям журнала ПредставлениеДанных БСП аудит изменений 8.3 8.5

Вы можете заказать платную адаптацию этой статьи под ваши задачи на «Бирже заказов».

  • 0% комиссии — оплата напрямую исполнителю;
  • Исполнители любого масштаба — от отдельных специалистов до команд под проект;
  • Прямой обмен контактами между заказчиком и исполнителем;
  • Безопасная сделка — при необходимости;
  • Рейтинги, кейсы и прозрачная система откликов.

См. также

Разработка Инструментарий разработчика Групповая разработка (Git, хранилище) Разработчик Платные (руб)

Практический курс по работе с AI-агентами для разработчиков 1С уровня middle и senior, а также тимлидов команд: от постановки задач и передачи контекста до создания расширений, интеграций, MCP-инструментов, тестов и проверки готового решения.

50000 руб.

10.09.2026    14013    125    0    

87

Инструментарий разработчика Чистка данных Свертка базы Инструменты администратора БД Системный администратор Разработчик Руководитель проекта 1С:Предприятие 8 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Управление нашей фирмой 3.0 Россия Платные (руб)

Инструмент представляет собой обработку для проведения свёртки или обрезки баз данных. Работает на ЛЮБЫХ конфигурациях (УТ, БП, ERP, УНФ, КА и т.д.). Поддерживаются серверные и файловые базы, управляемые и обычные формы, интерфейс 8.5. Может выполнять свертку одновременно в несколько потоков, а также без непосредственного участия пользователя. Решение в Реестре отечественного ПО.

24900 руб.

20.08.2024    83466    432    171    

364

Инструментарий разработчика Роли и права Запросы СКД Разработчик Руководитель проекта 1С:Предприятие 8 Платные (руб)

Инструменты для разработчиков 1С 8.3 и 8.5: Infostart Toolkit. Автоматизация и ускорение разработки на управляемых формах. Легкость работы с 1С.

16500 руб.

02.09.2020    286105    1608    423    

1220

Инструментарий разработчика Разработка Администрирование веб-серверов Системный администратор Разработчик Аналитик Руководитель проекта 1С 8.3 Платные (руб)

Analyzer 1C сводит выгрузку 1С — основную конфигурацию и все расширения — в единый граф знаний. Любой запрос по связям за доли секунды, с пометками «Доб.» / «Заимств.» / «Переопределено». Новое в 2.0 — обновление поставки: сравнение и объединение версий деревом «как в Конфигураторе» с выгрузкой плана решений; поиск конфликтов из-за перехватов расширений и висячих ссылок; загрузка из бинарных .cf/.cfe; циклические зависимости. Плюс анализ влияния, запросы BSL, роли и RLS, граф вызовов. Минута на развёртывание через Docker без необходимости подключения к Интернет. Любая 1С:Предприятие 8.3+.

14000 руб.

17.04.2026    17015    63    62    

74

Пакетная печать Печатные формы Инструментарий разработчика Разработчик 1С:Предприятие 8 Платные (руб)

Расширение для создания и редактирования печатных форм в системе 1С:Предприятие 8.3. Благодаря конструктору можно значительно снизить затраты времени на разработку печатных форм, повысить качество и прозрачность разработки, а также навести порядок в многообразии корпоративных печатных форм. Обновление версии от 21.04.26

22570 руб.

06.10.2023    44336    123    54    

135

Инструментарий разработчика Нейросети Платные (руб)

Первые попытки разработки на 1С с использованием больших языковых моделей (LLM) могут разочаровать. LLMки сильно галлюцинируют, потому что не знают устройства конфигураций 1С, не знают нюансов синтаксиса. Но если дать им подсказки с помощью MCP, то результат получается кардинально лучше. Далее в публикации: MCP для поиска по метаданным 1С, справке синтакс-помощника и проверки синтаксиса.

15250 руб.

25.08.2025    77223    147    41    

154

Разработка Инструментарий разработчика Разработчик Руководитель проекта 1С 8.3 Платные (руб)

Pilot 1C превращает задачу, поставленную обычными словами, в техническое задание, код на встроенном языке и сценарии проверки. Прежде чем что-то предложить, он сверяется с устройством вашей конфигурации через граф Analyzer 1C: существует ли объект, из чего он состоит, кто его вызывает, какие роли дают права. Чего найти не удалось – спрашивает, а не выдумывает. Готовый код проходит более полутора сотен проверок по справочнику языка и стандартам разработки, который приезжает вместе с продуктом. Модель – ваша: любой сервер, совместимый с программным интерфейсом OpenAI, в том числе локальный. Правки в конфигурацию Pilot не вносит – их применяет разработчик.

18300 руб.

11.09.2026    3852    5    0    

10

Инструменты администратора БД Инструментарий разработчика Роли и права Разработчик 1С:Предприятие 8 1C:Бухгалтерия Россия Платные (руб)

Расширение позволяет без изменения кода конфигурации выполнять проверки при вводе данных, скрывать от пользователя недоступные ему данные, выполнять код в обработчиках. Не изменяет данные конфигурации, легко устанавливается практически на любую конфигурацию на управляемых формах.

17000 руб.

10.11.2023    28827    104    46    

107
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. nedomolkov.ivan 527 30.09.26 11:15 Сейчас в теме
Приём со стартом сеанса хороший. Оговорка по масштабу: 25 секунд на 349 тысячах записей это маленький журнал. Если база пишет 150-190 млн событий в сутки, выгрузки за квартал уже не дождаться, и потолок в 10 000 там скорее страховка.

Мы в таком случае уносили журнал в ClickHouse, все ошибки за сутки там ищутся за 0,11 секунды: https://infostart.ru/1c/articles/2754296/
2. KonMa 118 30.09.26 11:55 Сейчас в теме
(1) Интересно, справедливо.
Но просто выложил то, что самому было нужно на днях)
На днях нужно было понять кто устроил бардак в бухе обменом. Истории изменения не было, а в ЖР было только написано толстый клиент, администратор. И вот получилось даже найти кто запускал обработку через путь к ней)
4. YA_93013054 20 30.09.26 13:44 Сейчас в теме
(1) Найти в ClickHouse строки по условию Level = 'Error' действительно занимает доли секунды, так как это простой индексный отбор по скалярной колонке. Но задача, которую решал автор статьи, принципиально сложнее:Собрать сквозную сеансовую цепочку по тройному ключу (ИмяКомпьютера + НомерСеанса + ВремяСтарта); Отфильтровать события подключения внешних обработок (_$Session$_.ExternalDataProcessorConnect); Распарсить внутреннюю структуру Данные для извлечения физического пути к файлу обработки (.epf); Отделить транзакции документов от фонового шума записей регистров по комбинации метаданных и ПредставлениеДанных. Если вы перенесете «сырой» журнал регистрации в ClickHouse, вам все равно придется реализовывать ту самую логику сопоставления сеансов и парсинга структуры данных, которую детально описал автор статьи. ClickHouse ускорит лишь физическое сканирование строк, но не отменит необходимости алгоритма группировки сеансов.
3. YA_93013054 20 30.09.26 12:53 Сейчас в теме
1) Ограничение ретроспективного анализа: Журнал регистрации фиксирует путь к запущенному файлу внешней обработки, но не сохраняет то, что именно этот файл делал внутри системы; связь между запуском обработки и изменением документов выводится косвенно по совпадению сеанса и времени.

2) Ловушки синтаксиса отборов: Опечатка в имени события платформы не вызывает исключение, а тихо возвращает пустую выборку, что может ввести исследователя в заблуждение.

3) Зависимость от полноты логов: Если журнал регистрации периодически очищается или настроен на минимальное логирование, описанные методы не сработают.
Для отправки сообщения требуется регистрация/авторизация