Здравствуйте!

Есть справочник "Контрагенты", в котором записаны клиенты. В числе реквизитов присутствует реквизит "Статус" со значениями "Новый клиент", "Постоянный клиент", "Ключевой клиент" и "Потерянный клиент". Значения статусов заданы в Перечислении "СтатусКлиента".

Нужно, чтобы изменения статуса клиента автоматически фиксировались в Регистре сведений "ИзменениеСтатуса" (Измерение - Контрагент (берётся из справочника "Контрагенты"), Ресурс - Статус (берётся из Перечисления "СтатусКлиента"). Для этого в модуле формы справочника "Контрагенты" написана процедура:

```1c
    &НаСервере
    Процедура СтатусКлиентаПриИзмененииНаСервере()
    РегистрыСведений.ИзменениеСтатуса.ПолучитьПоследнее();
    КонецПроцедуры

    &НаКлиенте
    Процедура СтатусКлиентаПриИзменении(Элемент)
    СтатусКлиентаПриИзмененииНаСервере();
    КонецПроцедуры
```

Однако при изменении никакие записи в Регистр автоматически не добавляются, а при открытии сам Регистр предлагает добавлять их вручную. Есть чёткое ощущение, что что-то где-то не доделано, но что?
---
Я тоже по
```1c
    РегистрыСведений.ИзменениеСтатуса.ПолучитьПоследнее();
```
 мог догадаться, но не дошло.

Вот простейший тогда пример, он будет создавать запись при любом сохранении контрагента

```1c
    &НаСервере
    Процедура ПриЗаписиНаСервере()

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

    ЗаписьРегистра = НаборЗаписей.Добавить();
    ЗаписьРегистра.Период = ТекущаяДата();
    ЗаписьРегистра.Контрагент = Объект.Ссылка;
    ЗаписьРегистра.Статус = Объект.Статус;
    НаборЗаписей.Записать();

    КонецПроцедуры
```

По хорошему надо проверять сменился статус или нет, а то будет много записей.
---
СтатусКлиентаПриИзмененииНаСервере() В этой процедуре смотрите как записывается.
---
Примерно вот так. Но все таки лучше это выполнять не при измении реквизита, а при записи объекта справочника т.к. можно изменить реквизит и не сохранить объект, а данные в регистре изменятся.

```1c
    &НаСервере
    Процедура СтатусПриИзмененииНаСервере()

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

    Если НаборЗаписей.Количество() > 0 Тогда

    ЗаписьРегистра = НаборЗаписей[0];
    ЗаписьРегистра.Контрагент = Объект.Ссылка;
    ЗаписьРегистра.Статус = Объект.Статус;
    НаборЗаписей.Записать();

    Иначе

    ЗаписьРегистра = НаборЗаписей.Добавить();
    ЗаписьРегистра.Контрагент = Объект.Ссылка;
    ЗаписьРегистра.Статус = Объект.Статус;
    НаборЗаписей.Записать();

    КонецЕсли;

    КонецПроцедуры

    &НаКлиенте
    Процедура СтатусПриИзменении(Элемент)
    СтатусПриИзмененииНаСервере();
    КонецПроцедуры
```
---
(3)
То есть, нужно описать событие ПриЗаписи?
---
ПриЗаписиНаСервере

В коде Объект.Ссылка и Объект.Статус по тексту заменить на ТекущийОбъект.Ссылка и ТекущийОбъект.Статус
---
```1c
    &НаСервере
    Процедура ПриЗаписиНаСервере()

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

    Если НаборЗаписей.Количество() > 0 Тогда

    ЗаписьРегистра = НаборЗаписей[0];
    ЗаписьРегистра.Контрагент = Объект.Ссылка;
    ЗаписьРегистра.Статус = Объект.Статус;
    НаборЗаписей.Записать();

    Иначе

    ЗаписьРегистра = НаборЗаписей.Добавить();
    ЗаписьРегистра.Контрагент = Объект.Ссылка;
    ЗаписьРегистра.Статус = Объект.Статус;
    НаборЗаписей.Записать();

    КонецЕсли;

    КонецПроцедуры
```

При замене Объект на ТекущийОбъект выдаётся ошибка о незаданной переменной.

А если оставить так, то при открытии РегистраСведений пишет о том, что период не может быть пустым:

"{Справочник.Контрагенты.Форма.ФормаЭлемента.Форма(20)}: Ошибка при вызове метода контекста (Записать)
        НаборЗаписей.Записать();
по причине:
Запись не верна! Период не может быть пустым!: ИзменениеСтатуса: 01.01.0001"
---
При замене Объект на ТекущийОбъект выдаётся ошибка о незаданной переменной.

Просто когда выбираешь в верхней части окна нужную процедуру он добавляет

```1c
    &НаСервере
    Процедура ПриЗаписиНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
```

Если руками писать, то тогда да, оставляем везде Объект.Ссылка.
---
А нигде информации не было что регистр периодический
---
Да, извиняюсь, что не указал это. Нужна именно история изменений статусов, так как при непериодическом он только одну строку записывает про каждого клиента и в ней меняет статус. При этом статус меняется только после обновления страницы.
Как сделать именно историю изменений (допустим, раз в секунду или раз в день - это сейчас неважно)?
Период "раз в секунду" я поставил для наглядности - просто чтобы видно было, что статус меняется.
---
Я тоже по
```1c
    РегистрыСведений.ИзменениеСтатуса.ПолучитьПоследнее();
```
 мог догадаться, но не дошло.

Вот простейший тогда пример, он будет создавать запись при любом сохранении контрагента

```1c
    &НаСервере
    Процедура ПриЗаписиНаСервере()

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

    ЗаписьРегистра = НаборЗаписей.Добавить();
    ЗаписьРегистра.Период = ТекущаяДата();
    ЗаписьРегистра.Контрагент = Объект.Ссылка;
    ЗаписьРегистра.Статус = Объект.Статус;
    НаборЗаписей.Записать();

    КонецПроцедуры
```

По хорошему надо проверять сменился статус или нет, а то будет много записей.
---
РС периодический?
---
Да. С изменением раз в секунду (для наглядности).
---
Тогда нахрена тебе реквизит в самом справочнике?
---
Такое условие поставлено. :) Так как, кроме всего прочего, требуется ещё вывод списка контрагентов с указанием их статуса. Поэтому и добавлен был этот реквизит.
---
Что запрещает выводить список контрагентов со статусом из РС?
---
Я понимаю, но задача у меня стоит сейчас следующая:

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

(15) Ничто не запрещает, но задача стоит - см. выше, какая.
---
И? Что мешает в карточке клиента показывать текущий статус из РС? И рядом кнопочку/ссылочку нарисовать на историю?
---
Именно показывать текущий статус ничего не мешает. Вопрос больше с историей изменений, ради которой и создан этот РС. В нём нужно именно историю изменений показывать, а не просто последний статус. А у меня только текущий статус там отражается, а те, что были до этого, нет. А надо, чтобы всё отражалось.
---
Где ТАМ?
---
Хм... каким-то странным образом всё заработало. :)

Всем спасибо. Особое спасибо "user620512". :) Отметил Ваш ответ, как решение.
---
Что заработало? Запись? Но ведь ты хотел ещё и отображение истории где-то "там"...
---
Ты понимаешь, что статус может изменяться какой-то периодической регламентной обработкой?
Как думаешь, что правильнее делать такой обработкой - переписывать объекты справочника совместно с добавлением записи в РС, или просто добавлять записи в РС?
---
Да. И запись заработала, и отражение истории. Во вложении скрин этого РС: первые 2 строки – как было сперва, вторые 3 – как должно быть.
---
Хммм... Похоже, я рано обрадовался: из 4-х контрагентов только 2 работают, как надо. А по 2-м остальным выдаётся ошибка
"{Справочник.Контрагенты.Форма.ФормаЭлемента.Форма(12)}: Ошибка при вызове метода контекста (Записать)
 НаборЗаписей.Записать();
по причине:
Запись не верна! Период не может быть пустым!: ИзменениеСтатуса: 01.01.0001 0:00:00, ООО "Всё для дома" (Регистр сведений: Изменение статуса; Номер строки: 1)"

Все 4 контрагента созданы по одному шаблону, примерно в одно и то же время, но 2 из них нормально отрабатывают, а 2 других вываливаются в ошибку. Отладка тоже показывает 2-х "правильных" контрагентов, а 2-х "неправильных" нет. :-( Период не указывается ни для одного контрагента
---
Продолжай наблюдать!
Если не умеешь записывать периодические регистры...
---
Это, конечно, очень полезная информация – то, что я не умею... Только я бы здесь и не писал, если бы всё знал и умел. :-)
А по существу моего вопроса? Каким образом моё умение/неумение влияет на то, что 2 контрагента нормально отрабатывают, а ещё 2 требуют указать период при том, что период не указывается ни в том, ни в другом случае? Ведь по идее работать всё должно одинаково – сведения о статусах должны фиксироваться для каждого контрагента независимо от того, что это за контрагент.
---
А записи без даты откуда появились? Попробуй руками любую дату меньше текущей занести у них и потом изменить статус через карточку контрагента.

п.с. такую ошибку можно получить если не устанавливать значение ЗаписьРегистра.Период, проверь что установка даты на месте.
---
Записи без даты появились, когда РС был непериодическим.

И опять-таки непонятно: в одно и то же время я создал 4-х контрагентов (набор реквизитов и всего прочего у всех 4-х одинаков). В итоге 2 контрагента при смене статуса отрабатывают стандартно, а ещё 2 ругаются на период. Где это чёртово значение периода нужно указать, и почему требуют указывать его только 2 контрагента из 4-х (ещё раз напишу: все 4 контрагента созданы в одно и то же время и имеют одинаковый набор характеристик)?
---
даты пустые заполнены и по этим котрагентам ругается?
---
Всё, я понял, почему ругался Регистр. Записи об этих 2 контрагентах, на которых он ругался (ИП Иванов А. Б. и ООО "Всё для дома", были первоначально созданы мной вручную через кнопку "Создать" (для пробы). После того, как я удалил эти записи из Регистра, всё заработало, как положено.

Извините, что отнял столько времени у вас. :-) В следующий раз постараюсь быть более краток. :-) А за подсказку ещё раз спасибо (13). :-)
---
Сообщение было скрыто модератором.
---
Не путаюсь. :-) 4 контрагента были созданы в справочнике "Контрагенты", а потом 2 из этих 4-х были добавлены мной вручную в РС, чего делать не стоило. Или, по крайней мере, давно уже надо было догадаться их удалить.
---
Сообщение было скрыто модератором.
---
а теперь новая вводная:

допустим Статус у контрагента изменили программно! (например регламентом или групповой обработкой)
или он изменился при обмене данных!

вся эта ваша свистопляска работать не будет!

(что бы работало, необходимо перенести функционал в модуль справочника Контрагенты, осилите?)
---
В модуль формы или в модуль объекта?
---
ну хорошо, если термин: в модуле справочника, вам не понятен, тогда пусть будет по вашему
в модуле объекта

(в событии ПриЗаписи(...) - здесь уже есть ссылка, даже у нового контрагента,
только добавьте проверку на то что Статус изменился)
---
Получилось решить данную задачу?
---
Да. Всё было сделано верно, а ошибка появлялась, как я понимаю, из-за того, что 2 первых записи были введены вручную. Не уверен, что причина ошибки именно в этом, но во всяком случае, после удаления этих 2-х записей всё стало работать, как надо.
---
У тебя остался dt файл? Хотел бы разобраться подробнее
---
(40)
Поищу. Если не найду, попробую по памяти восстановить.
---
Спасибо)
---
Нашёл.
История статусов реализована в РС "ИсторияСтатусовКлиентов", сами статусы заданы в Перечислении "СтатусКонтрагента". Контрагенты перечислены в соответствующем справочнике.
---
как ты реализовал историю статусов?
---
Получается каждый раз когда меняется дата статус должен автоматически меняться? Если 01.01 он был "Новый клиент" то после записи этого контрагента 10.01 он будет иметь статус "Потерянный клиент"? как тогда так сделать, чтобы автоматически проставлялся статус с учетом времени?