Методы Записать() и Очистить() у регистров

1. timeforlive 16 05.04.16 09:59 Сейчас в теме
Меня волнует следующий вопрос - в чем разница и схожесть двух методов Записать и Очистить.
Хочу обсудить с форумчанами следующие нюансы.
Рассмотрим применение этих методов в процедуре ОбработкаПроведения.
1. Если установлено свойство документа как Автоматически удалять старые движения (как-то так, 1с не под рукой, пишу с телефона), то не указав данные методы, все равно будет корректно вноситься записи в регистры. Верно?
2. Если вручную требуется удалять старые движения, то в чем разница какой метод использлвать в рамках текущей транзакции? Что Очистить, что Записать "обнуляет" записи для текущей транзакции, а при ее откате все отменяется и возвращается в исходное состояние. Другое дело, если бы мы завершили бы транзакцию, то Записать() стерла бы записи в регистры, а Очистить() очистила бы записи только для транзакции, но по ее завершении регистры бы остались в прежнем состоянии. Верно?

Пример применения методов:
Движения.Остатки.Записывать = Истина;
Движения.Остатки.Очистить();
Движения.Остатки.Записать();
По теме из базы знаний
Вознаграждение за ответ
Показать полностью
Ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
22. herfis 500 02.01.19 12:00 Сейчас в теме
(1) Все комментарии не читал, просто скажу следующее
Первое: Очистить() - никак не отражается на СУБД и никак с Записать() не связана. Это стандартная команда, как и у любой коллекции в памяти. Вызывается исключительно по необходимости, если в какой-то момент нужны гарантии того, что коллекция в памяти пустая. Тоже самое, как Очистить() у табличной части. Если после этого запишем, то запишется пустая табличная часть. Особенность только в том, что набор записей регистра всегда изначально пустой и для перезаписи старого набора его нужно вычитывать явно.
Второе Нужно четко разграничивать явную работу с набором записей и неявную работу через коллекцию наборов записей документа. При явной работе с конкретным набором записей разницы никакой нет. Что явно вызывается для набора записей то и будет происходить. Все ньюансы относятся к работе целиком с коллекцией наборов записей документа - явной или неявной. Так, на неявную работу Движения.Записать() уже влияют и признаки удаления движений, и выборочная запись наборов с признаком "Записывать". Это все для того, чтобы гарантировать единообразный порядок записи наборов.
2. timeforlive 16 05.04.16 10:00 Сейчас в теме
Вознаграждение с телефона только так можно добавить (вторым постом).
3. Glebis 13 05.04.16 15:08 Сейчас в теме
1) Если у набора стоит свойство Записывать = Истина, то набор будет записан сразу после выполнения кода "КонецПроцедуры" обработки проведения модуля объекта. Если "Удалять движения автоматически при отмене проведения", то будет ЗАМЕНЕН хранящийся набор записей, который будет получен с отбором по регистратору.
2) Не совсем понял вопрос. На набор движений транзакции всегда нужно накладывать отбор. Метод Очистить() очищает набор движений не тот что в БД, а только тот набор, который формируется в транзакции. Этот метод применяется в основном только после чтения (методом Прочитать()) набора движений транзакции с установленным отбором.
5. timeforlive 16 06.04.16 04:00 Сейчас в теме
(3) Glebis,
1. а мне казалось, что запись будет в момент исполнения метода движения Записать(). А при отмене транзакции (Например, отказ = истина) в момент исполнения КонецПроцедуры записи в регистре будут возвращены в исходное состояние.

2. Например, делаем записи:
движения.остатки.записывать = истина;
//движения.остатки.записать();
для стр из списокноменклатуры цикл
движение = ...Добавить();
// формируем добавление записей
конеццикла;
движения.остатки.записать();
Показать


В данном примере, Если "Удалять движения автоматически при отмене проведения" установлен в свойствах, нужен ли метод Записпть() до формирования записей?
6. spacecraft 06.04.16 07:11 Сейчас в теме
(5) timeforlive, перед началом формирования движений используйте метод очистить. Движения могут быть автоматически прочитаны и если не очистить, то будут дубли в регистре.
Если логика проведения требует контроля остатков по факту проведения (новый режим контроля остатков), тогда используйте Движения.Записать(), а не конкретное движение регистра. Так запишутся только движения помеченные записывать=истина. И не будет повторной записи по окончании обработчик проведения.
Для данного примера:
движения.остатки.записывать = истина;
движения.остатки.очистить();
для стр из списокноменклатуры цикл
движение = ...Добавить();
// формируем добавление записей
конеццикла;
движения.записать();
10. timeforlive 16 06.04.16 12:00 Сейчас в теме
(6) spacecraft, спасибо. Еще заметил здесь (сайт П.Чистова), что лучше использовать:
Движения.Записать()

Чтобы записать движения те, у которых установлен флаг "Записывать" в Истина, после чего этот флаг будет снят.
20. lic_avenger 10 29.12.18 11:13 Сейчас в теме
(10) На экзамене по платформе сказали, что записать() надо использовать всегда, а Чистов в своем видео использует только при оперативном проведении
21. timeforlive 16 01.01.19 10:50 Сейчас в теме
(20) Спасибо за информацию. Думаю - надо посмотреть в документации ИТС про требования к отраслевому Решению - как оно на практики то правильно, хех.
4. vkozak 05.04.16 16:34 Сейчас в теме
Чтобы применить "Очистить", нужно вначале прочитать набор записей,
Если использовать "Записать" для набора записей то все зависит от параметра Записать(Замещать), если он истина то новый набор заместит текущий, Аналог очистить.
Иначе новые записи будут добавляться к старому набору, если перед этим был применен метод "Прочитать" иначе также как и при установке по умолчанию новое затрет старое.
А еще, если не стоит Удалять Автоматически - то есть процедура "Обработка удаления проведения" где и прописывается что делать при отмене проведения.
7. Glebis 13 06.04.16 07:29 Сейчас в теме
1) Принудительная запись набора транзакции методом Записать() не рекомендуется жёлтой библией (уровень 1С совместимо, по моему), т.к. набор будет записывать дважды: методом Записать(), и при Записывать = Истина и "Записывать движения" = "Записывать Выбранные" в конце процедуры ОбработкаПроведения. Есть смысл этого метода только для нового метода проверки остатков и ооочень редко для формирования одинаковой последовательности записей наборов в регистры, что предотвратит возможную взаимоблокировку при конкуренции транзакций.
2) В такой форме без отбора сотрутся ВСЕ записи регистра. Метод Записать() вообще незачем использовать, набора и так запишется. Записывать = истина по умолчанию. Если "Удалять движения автоматически при отмене проведения", то платформы ПЕРЕД записью для каждого подчинённого регистра сделает примерно следующее:
СуществующееДвижение = РегистрыСведений.Регистр.СоздатьНаборЗаписей();
СуществующееДвижение.Отбор.Регистратор = ТекущийРегистратор;
// Запись пустого набора.
СуществующееДвижение.Записать(Истина)
8. spacecraft 06.04.16 08:06 Сейчас в теме
(7) Glebis, про 2 пункту совсем не верно.
ВСЕ записи точно не сотрутся.
При "Удалять движения автоматически при отмене проведения" ничего "такого" не сделает.
Пустой набор перед обработчиком проведения записывается только в режиме "Удалять автоматически".
9. Glebis 13 06.04.16 09:18 Сейчас в теме
Да, виноват, не написал что пустой набор пишется только при отмене проведения (в т.ч. при перепроведении)...
11. timeforlive 16 06.04.16 12:04 Сейчас в теме
Мое мнение - для того, чтобы очистить движения (в транзакции) для предотвращения дублей при записи, следует использовать метод Очистить().
А метод Записать() следует использовать только для прямого его назначения - записи движения в регистр (в том числе пустые движения, т.е. с целью очистить движения в БД).
12. hroa 06.04.16 16:55 Сейчас в теме
Очистить() не поможет для предотвращения дублей, поэтому вообще его можете не применять.
13. spacecraft 06.04.16 18:04 Сейчас в теме
(12) hroa, этому есть обоснование?
14. timeforlive 16 15.04.16 06:26 Сейчас в теме
(12) hroa, вы правы. (13) spacecraft, в случае перепроведения метод Очистить() не спасет от дублей, т.к. в БД есть записи документа, который мы перепроводим. То есть, нужно:
Движения.Остатки.Записывать = Истина;
Движения.Остатки.Записать();

После чего получить результат запроса, в котором обращаемся к регистру "Остатки". Если метод Записать() не применить, то будут считаны движения настоящего документа.

А метод Очистить() использовать в случае, когда явно был прочитан набор записей (методом "Прочитать"), как правильно заметил (4) vkozak.

Конечно, это не универсальное решение (как "черное и белое"), ибо в каждой конкретной прикладной задачи требуются свои условия - свои "## оттенков серого" ^_^
16. spacecraft 15.04.16 07:46 Сейчас в теме
(14) timeforlive, пока у Вас ложные (не полные) представления о механике проведения.
Рекомендую почитать http://1c.chistov.pro/2013/07/blog-post_25.html.
timeforlive; +1 Ответить
17. timeforlive 16 16.04.16 08:48 Сейчас в теме
(16) spacecraft, отнюдь, в книге "приемы программирования" про Записать так и говорится. Буду за компом, найду и зацитирую.
за ссылку спасибо, читал, потому и возникли вопросы и разногласия касптельно настоящей темы
18. timeforlive 16 16.04.16 08:57 Сейчас в теме
(16) spacecraft, метод Очистить() очищает полученные записи регистра. Получить их можно явно (см. выше) и не явно, когда система сама считывает в след. случаях:
1. свойство Удаление Движений установлено как Не удалять движения;
2. при открытии УФ, если на ней размещено поле с движениями
3. установлен флаг ИсползоватьВсегда в УФ для Движений
4. при открытии обычных форм (всегда)

Следовательно, нужно:

Записывать()
Очистить()
Записать()
Запрос.Выполнить
Движения.Р.Добавит()
// если 1 из нескольких, то
Дижения.Р.Записать()
// если по всем реоистрам, то
Движения.Записать()
19. spacecraft 16.04.16 11:12 Сейчас в теме
(18) timeforlive, уже лучше.
Только ни слова не сказано почему считаете, что это правильно?
Очистить() не поможет для предотвращения дублей, поэтому вообще его можете не применять.

Дубли в регистре и анализ актуальных данные без учета движений самого документа это совсем разные вещи. Для анализа данных в регистре рекомендуется новый способ проведения.
Ну и Движения.Р.Записать() рекомендуется делать только в особых случаях. Как правило лучше совсем этого избегать.
15. Doom2w 26 15.04.16 07:01 Сейчас в теме
Движения.Остатки.Записывать = Истина;
Движения.Остатки.Очистить();
Движения.Остатки.Записать();


Записывать - Указываем, что набор записей в БД запишется после метода записать.
Очистить - очищаем набор записей. (вдруг что-то считали)
Записать - записываем набор записей (в нашем случае пустой)


Данные конструкция нужна для того чтобы при проведение предыдущие движения Регистра не влияли на логику проведения.
timeforlive; +1 Ответить
23. herfis 500 02.01.19 12:16 Сейчас в теме
Тьфу. Только сейчас заметил, что некроветка.
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот