Имя: Пароль:
1C
1С v8
v8: Как программно менять записи регистра сведений?
0 oslokot
 
08.02.13
10:28
Прошу простить за глупые вопросы, я пока что клюшечник :)

Нужно пробежаться по регистру сведений и при определенных уловиях сделать в нем некоторые изменения. Вот такой у меня получился быдло-код:
Процедура КнопкаВыполнитьНажатие(Кнопка)
   ТекущаяДата = ТекущаяДата();
   Рег = РегистрыСведений.ДокументыНоменклатурыДоп;
   Выборка = Рег.Выбрать();
   Пока Выборка.Следующий() Цикл
       ТекущийСтатус    = Выборка.Статус1;
       ДатаВыдачи        = Выборка.Документ.ДатаНачала;
       СрокДействия    = Выборка.Документ.ДатаОкончания;
       Если ((ЗначениеЗаполнено(ДатаВыдачи) = Ложь) И (ЗначениеЗаполнено(СрокДействия) = Ложь)) ИЛИ (ЗначениеЗаполнено(СрокДействия) = Ложь) Тогда
           // Не все даты заполнены, устанавливаем статус "Неопределено"
           УстановитьНовыйСтатус(Перечисления.СтатусыДокументовДоп1.Неопределено);
           Продолжить;
       КонецЕсли;
       // Проверка на дату в интервале
       Если ТекущаяДата >= ДатаВыдачи И ТекущаяДата <= СрокДействия Тогда
           Если ТекущийСтатус <> Перечисления.СтатусыДокументовДоп1.Действующий Тогда
               // Вышли из допустимого интервала, устанавливаем статус "Архивный"
               УстановитьНовыйСтатус(Перечисления.СтатусыДокументовДоп1.Архивный);
           КонецЕсли;
       КонецЕсли;
       // Проверка на превышение
       Если ТекущаяДата > СрокДействия Тогда
           Если ТекущийСтатус <> Перечисления.СтатусыДокументовДоп1.Архивный Тогда
               // Превысили срок действия, устанавливаем статус "Архивный"
               УстановитьНовыйСтатус(Перечисления.СтатусыДокументовДоп1.Архивный);
           КонецЕсли;
       КонецЕсли;
   КонецЦикла;
КонецПроцедуры

Процедура УстановитьНовыйСтатус(ТипСтатуса)
   // Здесь нужно присвоить новый статус в регистр и сохранить изменения    
КонецПроцедуры

1 вопрос. Правильно ли я использую операторы сравнения или можно как-то по другому?
2 вопрос. Правильно ли я обращаюсь к перечислениям?
3 вопрос. Собственно, как осуществить запись в регистр сведений? :)
1 Галахад
 
гуру
08.02.13
10:29
Для новичков есть книжка. Простые примеры.
2 zak555
 
08.02.13
10:29
наборзаписей с отбором по определенным условиям
3 cw014
 
08.02.13
10:30
1 и 3 неправильно. Делай запросом, выбирай только то, что нужно. Потом создавай менеджер записи и по ключевым полям меняй данные
4 Cube
 
08.02.13
10:30
(0) Выбрать и сравнить надо в запросе.
5 2S
 
08.02.13
10:31
Семеречный подход. Чувствуется. Набор записей юзай.
6 zak555
 
08.02.13
10:31
> при определенных уловиях сделать в нем некоторые изменения

что за условия ?
РС подчинён регистратору ?
7 oslokot
 
08.02.13
10:36
(3) (4) да, но запрос пока для меня сложен. Хорошо, попробую. (5) ага
(6) условия - это простые сравнения дат. Регистратора нет.
8 GANR
 
08.02.13
10:36
(0)
Перечисления.СтатусыДокументовДоп1.Действующий - это запрос к жесткому диску в цикле (по замеру в этом месте увидишь тормоза) - рекомендую один раз за рамками цикла

МенеджерПеречисления = Перечисления.СтатусыДокументовДоп1;
СтатусДействующий = МенеджерПеречисления.Действующий;
СтатусАрхивный = МенеджерПеречисления.Архивный;
СтатусНеопределено = МенеджерПеречисления.Неопределено;

ПОка ... Цикл

   ...

   Если ТекущийСтатус <> СтатусДействующий Тогда
       // Превысили срок действия, устанавливаем статус "Архивный"
       УстановитьНовыйСтатус(СтатусНеопределено);
   КонецЕсли;
   
   ...

   Если ТекущийСтатус <> СтатусАрхивный Тогда
       // Превысили срок действия, устанавливаем статус "Архивный"
       УстановитьНовыйСтатус(СтатусАрхивный);
   КонецЕсли;

КонецЦикла;
9 Cube
 
08.02.13
10:38
(7) "запрос пока для меня сложен"
В v8 конструктор запросов просто сказка. Ты открой и посмотри, там всё просто.
10 zak555
 
08.02.13
10:38
(7) хоть бы структуру регистра описал + какие данные условия
11 GANR
 
08.02.13
10:43
Вот 1 из способов записи в РС

   НаборЗаписей = РегистрыСведений.ТвойРегистрСведений.СоздатьНаборЗаписей();
   НаборЗаписей.Отбор.ТвоеИзмерение1.Установить(ТвоеЗначениеИзмерения1);
   НаборЗаписей.Отбор.ТвоеИзмерение2.Установить(ТвоеЗначениеИзмерения2);
   ...
   НаборЗаписей.Отбор.ТвоеИзмерениеN.Установить(ТвоеЗначениеИзмеренияN);

   // Твой алгоритм заполнения набора записей
   ...
   // конец алгоритма

   НаборЗаписей.Записать();

ВНИМАНИЕ!!! Если сделать запись в РС без отбора - можно грохнуть ВСЕ записи РС, какие там есть, кроме тех, которые есть в таком наборе. Осторожнее с этим !
12 oslokot
 
08.02.13
10:44
(8) Принято, спасибо.
(9) да, я видел. Просто решил пока выборкой пройтись
(10) простейший регистр, без регистратора
Измерения: Номенклатура (спр.ссылка) и Документ (спр.ссылка)
Ресурсы: Статус (перечисление)
Просто тупо пробежаться по нему и вместо Статуса записать другой Статус
13 zak555
 
08.02.13
10:44
(11) у записать есть параметр
14 GANR
 
08.02.13
10:48
(13) Ну, подробнее - в синтаксис-помощник.
15 oslokot
 
08.02.13
10:51
(11) хорошо, пробую..
16 oslokot
 
08.02.13
11:16
(11) непойму все-равно как писать в ресурс.
Вот, например сделал отбор по измерениям
   Рег = РегистрыСведений.ДокументыНоменклатурыДоп;
   Выборка = Рег.Выбрать();
   Пока Выборка.Следующий() Цикл
       НаборЗаписей = РегистрыСведений.ДокументыНоменклатурыДоп.СоздатьНаборЗаписей();
       НаборЗаписей.Отбор.Номенклатура.Установить(Выборка.Номенклатура);
       НаборЗаписей.Отбор.Документ.Установить(Выборка.Документ);
   КонецЦикла;

А как теперь в ресурс с именем "Статус1" записать новый статус?
17 GANR
 
08.02.13
11:33
(16) НаборЗаписей[0].ТвойРесурс
18 GANR
 
08.02.13
11:34
(16) Это, кстати, опять запрос в цикле
19 oslokot
 
08.02.13
11:41
Так, стоп. Давайте по другому. Вот сделал запрос.
Работает мгновенно, не ожидал!

Процедура Кнопка1Нажатие(Элемент)
   Запрос = Новый Запрос;
   Запрос.Текст =
   "ВЫБРАТЬ
   |    ДокументыНоменклатурыДоп.Документ,
   |    ДокументыНоменклатурыДоп.Статус1
   |ИЗ
   |    РегистрСведений.ДокументыНоменклатурыДоп КАК ДокументыНоменклатурыДоп
   |ГДЕ
   |    ДокументыНоменклатурыДоп.Документ.ДатаОкончания < &ТекущаяДата
   |
   |СГРУППИРОВАТЬ ПО
   |    ДокументыНоменклатурыДоп.Документ,
   |    ДокументыНоменклатурыДоп.Статус1" ;
   Запрос.УстановитьПараметр("ТекущаяДата", ТекущаяДата());
   Выборка = Запрос.Выполнить().Выбрать();
   Пока Выборка.Следующий() Цикл
       Сообщить(Выборка.Статус1);
   КонецЦикла;
КонецПроцедуры

Выводит в табло статусы

Теперь мне нужно в этом цикле выборки юзать наборзаписей?
20 hhhh
 
08.02.13
11:46
чтобы быстро надо так

ВЫБРАТЬ
   |    ДокументыНоменклатурыДоп.Документ,
   |    ДокументыНоменклатурыДоп.Документ.ДатаНачала КАК ДатаВыдачи,
   |    ДокументыНоменклатурыДоп.Документ.ДатаОкончания КАК СрокДействия,
   |    ДокументыНоменклатурыДоп.Статус1

привыкай уже.
21 hhhh
 
08.02.13
11:47
всё надо выбирать в запросе, а не писать офигенные тормоза типа

   СрокДействия     = Выборка.Документ.ДатаОкончания;
22 GANR
 
08.02.13
12:00
(16) Набор записей нужно править примерно так (курсы Чистова, Гилева и Насипова):

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

Отбор = Новый Структура;

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

НаборЗаписей.Записать();
23 oslokot
 
08.02.13
12:49
(20) (22)  спасибо за подсказки!
24 oslokot
 
08.02.13
13:58
Вот так получилось в итоге:
Процедура КнопкаВыполнитьНажатие(Кнопка)
   МенеджерПеречисления    = Перечисления.СтатусыДокументовДоп1;
   СтатусАрхивный            = МенеджерПеречисления.Архивный;
   
   Запрос = Новый Запрос;
   Запрос.Текст =
   "ВЫБРАТЬ
   |    ДокументыНоменклатурыДоп.Документ,
   |    ДокументыНоменклатурыДоп.Документ.ДатаНачала КАК ДатаВыдачи,
   |    ДокументыНоменклатурыДоп.Документ.ДатаОкончания КАК СрокДействия,
   |    ДокументыНоменклатурыДоп.Статус1 КАК ТекущийСтатус
   |ИЗ
   |    РегистрСведений.ДокументыНоменклатурыДоп КАК ДокументыНоменклатурыДоп
   |ГДЕ
   |    ДокументыНоменклатурыДоп.Документ.ДатаОкончания < &ТекущаяДата
   |
   |СГРУППИРОВАТЬ ПО
   |    ДокументыНоменклатурыДоп.Документ,
   |    ДокументыНоменклатурыДоп.Статус1" ;
   
   Запрос.УстановитьПараметр("ТекущаяДата", ТекущаяДата());
   Выборка = Запрос.Выполнить().Выбрать();
   
   НаборЗаписей = РегистрыСведений.ДокументыНоменклатурыДоп.СоздатьНаборЗаписей();
   НаборЗаписей.Прочитать();
   
   Отбор = Новый Структура;
   
   Для Каждого Запись Из НаборЗаписей Цикл
       Отбор.Вставить("Документ", Запись.Документ);
       Отбор.Вставить("ТекущийСтатус", Запись.Статус1);
       Выборка.Сбросить();
       Если Выборка.НайтиСледующий(Отбор) Тогда
           Запись.Статус1 = СтатусАрхивный;
       КонецЕсли;
   КонецЦикла;
   НаборЗаписей.Записать();    
   
КонецПроцедуры

Работает правильно.
Что скажете?
25 GANR
 
08.02.13
14:15
(24) Замер производительности в помощь.
Можно ещё модифицировать алгоритм, то есть НаборЗаписей.Прочитать() - убрать, в цикле Выборка.Следующий() Запись = НаборЗаписей.Добавить(), а в конце НаборЗаписей.Записать(Ложь), но при этом надо заполнять измерения. Существующая версия кода записывает весь имеющийся набор, зато не требует по новой заполнять измерения и реквизиты, а новая перезапишет только то, что добавлено в набор.
26 GANR
 
08.02.13
14:16
Смысл (25) понятен?
27 oslokot
 
08.02.13
14:26
(26) ага, понял! спасибо