Как добавить реквизит, изменить проводки типовой и не поиметь геморроя при обновлении (пример для бух 3.0)

10.11.13

База данных - Обновление 1С

Пришли ко мне бухи и говорят:
- у нас в 7.7 было окошко в документе с датами оплаты для книги покупок, сделай нам в 3.0 такое-же.
Ну я типа
- так придется снимать с поддержки, потом при любом обновлении Вам придется все тестировать.... короче геморрой и мне и Вам!
Бухи слезно
- ну надо, очень!
Почесал я репу и стал думать, как и на елку залезть и попу не уколоть...

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

Соответственно создаю регистр  "ДатыКнигиПокупок" (измерения Документ и Дата, на один документ может быть несколько дат) и общий модуль "Мув_ДополнительныеСообщенияПроведения".  Далее снимаю с поддержки форму документа "СчетФактураПолученный" и в ней добавляем

&НаСервере

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

                // vde69 - сохранение реквизита "Мув_ДатаОплаты"

                Мув_ДополнительныеСообщенияПроведения.ПередЗаписьюНаСервере(ЭтаФорма, Отказ, ТекущийОбъект, ПараметрыЗаписи);

                // vde69 - Конец сохранения реквизита "Мув_ДатаОплаты"

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

 

&НаСервере

Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

                // vde69 - Добавление реквизита "Мув_ДатаОплаты"

                Мув_ДополнительныеСообщенияПроведения.ФормаПриСозданииНаСервере(ЭтаФорма, "Продавец", "ГруппаШапкаПравая");

                // vde69 - Конец добавления реквизита "Мув_ДатаОплаты"

 

 

Собственно это все что мне придется контролировать при обновлении. Далее делаем 2 подписки на событие

"ПриЗаписиДокументовКнигиПокупок" и "ПриПроведенииДокументовКнигиПокупок", идем в новый модуль и там пишем

 

Процедура ПроведениеДокументовОбработкаПроведения(Источник, Отказ, РежимПроведения) Экспорт

                Если Источник.ОбменДанными.Загрузка Тогда

                               Возврат;

                ИначеЕсли Отказ Тогда

                               Возврат;

                КонецЕсли;

                УстановитьПривилегированныйРежим(Истина);

                Если Метаданные.Документы.Содержит(Источник.Ссылка.Метаданные()) Тогда

                             ДополнительныеДвижения(Источник);

                КонецЕсли;

                УстановитьПривилегированныйРежим(Ложь);

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

 

Процедура ПриЗаписиДокументовКнигиПокупокПриЗаписи(Источник, Отказ) Экспорт

                Перем МассивДатОплатКнигиПокупок;

               

                Если Источник.ДополнительныеСвойства.Свойство("МассивДатОплатКнигиПокупок", МассивДатОплатКнигиПокупок) = Истина Тогда

                               // сохранение дат в регистр

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

                               мРег.Отбор.Документ.Установить(Источник.Ссылка, Истина);

                               мРег.Прочитать();

                               мТЗ = мРег.ВыгрузитьКолонки();

                               Для Каждого эл из МассивДатОплатКнигиПокупок Цикл

                                               НоваяСтрока = мТЗ.Добавить();

                                               НоваяСтрока.Документ = Источник.Ссылка;

                                               НоваяСтрока.Дата = Эл;

                               КонецЦикла;

                               мРег.Загрузить(мТЗ);

                               мРег.Записать(Истина);

                Иначе

                               // это запись не из формы - нужно прочитать из регистра и положить в доп свойства

                               Запрос = Новый Запрос(

                               "ВЫБРАТЬ

                               |             ДатыКнигиПокупок.Дата

                               |ИЗ

                               |             РегистрСведений.ДатыКнигиПокупок КАК ДатыКнигиПокупок

                               |ГДЕ

                               |             ДатыКнигиПокупок.Документ = &Документ");

                              

                               Запрос.УстановитьПараметр("Документ", Источник.Ссылка);

                               МассивДатОплатКнигиПокупок = Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Дата");

                               Источник.ДополнительныеСвойства.Вставить("МассивДатОплатКнигиПокупок", МассивДатОплатКнигиПокупок);

                КонецЕсли;

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

 

Процедура ФормаПриСозданииНаСервере (КонтекстФормы, ИмяСледующегоРеквизита, ИмяГруппыВставки) Экспорт

                // добавляем текстовый реквизит "Мув_ДатаОплаты" в группу "ИмяГруппыВставки" перед элементом "ИмяСледующегоРеквизита"

                // заполняет этот реквизит из регистра

               

                Объект = КонтекстФормы.РеквизитФормыВЗначение("Объект");

                ДобавляемыеРеквизиты = Новый Массив;

                мРеквизиты = КонтекстФормы.ПолучитьРеквизиты();

                РеквизитЕсть = Ложь;

                Для Каждого тРек из мРеквизиты Цикл

                               Если "Мув_ДатаОплаты" = тРек.Имя Тогда

                                               РеквизитЕсть = Истина;

                               КонецЕсли;

                КонецЦикла;

                Если не РеквизитЕсть Тогда

                               КС = Новый КвалификаторыСтроки(100);

                               Массив = Новый Массив;

                               Массив.Добавить(Тип("Строка"));

                               ОписаниеТиповС = Новый ОписаниеТипов(Массив, , КС);

                               ДобавляемыеРеквизиты.Добавить(Новый РеквизитФормы("Мув_ДатаОплаты", ОписаниеТиповС));

                КонецЕсли;

                КонтекстФормы.ИзменитьРеквизиты(ДобавляемыеРеквизиты);

               

                // заполним реквизит

                Запрос = Новый Запрос(

                "ВЫБРАТЬ

                |             ДатыКнигиПокупок.Дата

                |ИЗ

                |             РегистрСведений.ДатыКнигиПокупок КАК ДатыКнигиПокупок

                |ГДЕ

                |             ДатыКнигиПокупок.Документ = &Документ");

                Запрос.УстановитьПараметр("Документ", Объект.Ссылка);

                мТекст = "";

                Выборка = Запрос.Выполнить().Выбрать();

                Пока Выборка.Следующий() Цикл

                               мТекст = мТекст + ";" + Формат(Выборка.Дата, "ДЛФ=D");

                КонецЦикла;

                Если Лев(мТекст, 1) = ";" Тогда

                               мТекст = Сред(мТекст, 2);

                КонецЕсли;

                КонтекстФормы.Мув_ДатаОплаты = мТекст;

                // создание поля на форме

                СледующийРеквизит = КонтекстФормы.Элементы.Найти(ИмяСледующегоРеквизита);

                ГруппаДляВставки = КонтекстФормы.Элементы.Найти(ИмяГруппыВставки);

               

                Для Каждого эл из ДобавляемыеРеквизиты Цикл

                               НовыйЭлемент = КонтекстФормы.Элементы.Вставить(эл.Имя, Тип("ПолеФормы"), ГруппаДляВставки, СледующийРеквизит);

                               НовыйЭлемент.ПутьКДанным = эл.Имя;

                               НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода;

                               НовыйЭлемент.Заголовок = "Даты оплаты";

                КонецЦикла;

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

 

Функция ПривестиКДате (ДатаСтрокой, Формат)

                сГод = "";

                сМесяц = "";

                сДень = "";

                сДлина = стрДлина(Формат);

                Для сч = 1 по сДлина Цикл

                               СимволФормата = Сред(Формат, сч, 1);

                               Если СимволФормата = "d" Тогда

                                               сДень = сДень + Сред(ДатаСтрокой, сч, 1);

                               ИначеЕсли СимволФормата = "M" Тогда

                                               сМесяц = сМесяц + Сред(ДатаСтрокой, сч, 1);

                               ИначеЕсли СимволФормата = "y" Тогда

                                               сГод = сГод + Сред(ДатаСтрокой, сч, 1);

                               КонецЕсли;

                КонецЦикла;

                Попытка

                               Результат = Дата(Число(сГод), Число(сМесяц), Число(сДень));

                Исключение

                               Результат = Неопределено;

                КонецПопытки;

                Возврат Результат;

КонецФункции

 

Процедура ПередЗаписьюНаСервере(КонтекстФормы, Отказ, ТекущийОбъект, ПараметрыЗаписи) Экспорт

                Если Отказ Тогда

                               Возврат;

                КонецЕсли;

                Попытка

                               МассивДатОплатКнигиПокупок = Новый Массив;

                               мСтрока = КонтекстФормы.Мув_ДатаОплаты;

                               мМассив = СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок(мСтрока, ";", Ложь);

                               мТекст = "";

                               Для Каждого эл из мМассив Цикл

                                               мДата = ПривестиКДате (эл, "dd.MM.yyyy");

                                               МассивДатОплатКнигиПокупок.Добавить(мДата);

                                               нДата = Формат(мДата, "ДЛФ=D");

                                               Если нДата <> эл Тогда

                                                               ВызватьИсключение "Ошибка форматы даты";          

                                               КонецЕсли;

                                               мТекст = мТекст + ";" + Формат(нДата, "ДЛФ=D");

                               КонецЦикла;

                               Если Лев(мТекст, 1) = ";" Тогда

                                               мТекст = Сред(мТекст, 2);

                               КонецЕсли;

                               КонтекстФормы.Мув_ДатаОплаты = мТекст;

                               ТекущийОбъект.ДополнительныеСвойства.Вставить("МассивДатОплатКнигиПокупок", МассивДатОплатКнигиПокупок);

                Исключение

                               Отказ = Истина;

                               Сообщить("Ошибка формата даты оплаты");

                КонецПопытки;

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

 

результат:

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

 

Все бухи довольны, система надежна на отказ, обновление почти безболезнены...

 

См. также

Обновление 1С Linux Системный администратор Программист Бесплатно (free)

Пошаговая инструкция для обновления платформы 1С на сервере Linux Debian.

28.03.2025    394    California_Dreaming    2    

5

Обновление 1С Программист Платформа 1С v8.3 Россия Бесплатно (free)

При обновлении релиза конфигурации УТ появилась ошибка "Ошибка формата потока".

21.03.2025    922    Gummi_pr    10    

7

Обновление 1С Программист Платформа 1С v8.3 1С:ERP. Управление холдингом Абонемент ($m)

Описан практический пример обновления через копию конфигурации 1С:ERP. Управление холдингом с версии 3.2.6.6 на версию 3.2.6.7, который можно применять на других конфигурациях и версиях.

10 стартмани

18.02.2025    872    PetrovAnton    6    

5

Обновление 1С Программист Платформа 1С v8.3 Абонемент ($m)

Отчет о сравнении конфигураций представляет собой обширный массив информации. Однако у него есть значительное ограничение: его невозможно настраивать, например, добавлять различные группировки, фильтры или сортировку данных. Тем не менее, если преобразовать этот отчет в таблицу и использовать её в качестве источника данных, это открывает возможность для создания универсального отчета с использованием группировок, отборов и сортировки

10 стартмани

18.02.2025    762    5    kalyaka    0    

7

Обновление 1С Программист Платформа 1С v8.3 Абонемент ($m)

При длительном обновлении из конфигуратора следим за процентом загрузки ПК и отправляем письмо на почту при завершении.

1 стартмани

17.02.2025    361    0    slavik27    0    

3

Обновление 1С Запросы Программист Платформа 1С v8.3 1С:ERP Управление предприятием 2 Абонемент ($m)

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

2 стартмани

06.02.2025    2030    16    XilDen    26    

35
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. IamAlexy 345 10.11.13 17:32 Сейчас в теме
а дополнительные реквизиты и сведения нельзя было использовать чтобы не городить этот огород?
2. vde69 925 10.11.13 19:12 Сейчас в теме
(1) каким образом дополнительные сведения будут делать проводки?

правильно только через подписку, но хитрость в том, что в подписку гарантировано передать параметр формы сложно :) по сколько 1с не регламентирует порядок вызова подписчиков мы не имеем гарантированного знания записаны данные формы в регистр или нет. Да и контекст формы в подписку не передается... Беда однако :)
3. Aleksey_3 10.11.13 20:14 Сейчас в теме
(2) А зачем тебе параметры формы?

Фишка в том что у Доп.сведений не бывает неактуального состояния (когда данные на форме отличаются от данных в БД). Плюс пользователь не сможет добавить значения не записав объект, т.е. если у тебя есть ссылка на объект, то смело читай из РС данные - они там в актуальном состоянии

Из минусов - нельзя штатно на форму вывести
6. vde69 925 11.11.13 08:28 Сейчас в теме
(3) (4) как в доп свойствах хранить список дат ? и как его вывести на форму, что-бы было "как в 7.7" ???

доп свойства хороши для требуемых значений (типа вложеного файла), но основные реквизиты нужны именно на форме :)
7. Armando 1402 11.11.13 10:09 Сейчас в теме
(6)
как в доп свойствах хранить список дат ?

да никак)
Меня больше волнует зачем доп. регистр делать? Можно тогда табличной частью документа обойтись.
8. vde69 925 11.11.13 10:43 Сейчас в теме
(7) конечно можно и ТЧ сделать, но опять возвращаемся к тому что у меня система отказоустойчивая.

это означает, что если документ полностью вернуть на поддержку и перепровести всю базу все мои дополнительные проводки останутся :) (не смотря на то, что с формы поле исчезнет).

Варианты когда по неосторожности при обновлении удаляли реквизит я видел пару раз.
9. vde69 925 11.11.13 10:43 Сейчас в теме
(8)+
кроме того регистр рулит если понадобится это поле внести еще в пяток других документов :)
4. Armando 1402 10.11.13 22:03 Сейчас в теме
Зачем этот огород в виде дополнительного регистра?
Если доп. реквизиты не хочется использовать, то можно смело делать реквизиты документа. Я бы не боялся возврата документа на поддержку, ибо если решились снять, то назад редко возвращают. Тем более, что создание новых реквизитов на сложность обновления практически не влияет. И форму можно сделать так, чтобы при обновлении почти не заморачиваться. Программно добавлять реквизиты на форму.
Пример для формы:
// Типовой обработчик
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	// Тут типовой код
КонецПроцедуры


// Свой подключаемый обработчик
&НаСервере
Процедура Подключаемый_ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	
	// Вызов типового обработчика
	ПриСозданииНаСервере(Отказ, СтандартнаяОбработка);
	
	// Тут свой код
	
КонецПроцедуры

#Если Сервер Тогда
УстановитьДействие("ПриСозданииНаСервере", "Подключаемый_ПриСозданииНаСервере");
#КонецЕсли
Показать

Емельянов Алексей; PowerBoy; afanasko; zqzq; Lusik; +5 Ответить
5. Armando 1402 10.11.13 22:04 Сейчас в теме
10. Stas_Gromov 37 13.11.13 06:46 Сейчас в теме
Тут про оптимизацию сложно говорить. База может стоять на поддержке с возможностью изменения, это типовой момент.
полностью вернуть на поддержку

не совсем понятно что автор имеет ввиду: зачем ИЗНАЧАЛЬНУЮ конфу снимать с поддержки? Достаточно просто включить Разрешить изменения. И всё! Базу можно нормально обновлять, перенося свои изменения. Если мы добавили РЕКВИЗИТЬ документу, и кинули его на форму, то при обновлении максимум исчезает наш реквизит с формы, в конфе он остаётся, соответственно данные тоже остаются, достаточно вернуть его на форму.
То же касается и модуля: один фиг переносить код. Можно добавить в ОбработкеПроведения 1 строчку с вызовом СВОЕГО модуля проведения. После обновления вернуть эту 1 строчку на место и всё, больше ничего не надо!
ИМХО автор пытался изобрести велосипед, один хрен колёса квадратные получились!
suggestive; +1 Ответить
11. Kov495 11 13.11.13 09:08 Сейчас в теме
Идея хорошая в задумке, но можно подумать о ее упрощении.
12. ser6702 176 13.11.13 10:14 Сейчас в теме
Реквизиты ка кправило не пропадают при обновлении - пропадают только на форме. А чтоб этого не было элементы формы прописываются кодом. Тогда обновляя форму видны внесенные изменения и вс кошоладно. В принципе возможно все доработки форм внести в обработку, которую можно накатить на типовую базу и получить доработанную в идеале.
13. DAnry 9 13.11.13 20:56 Сейчас в теме
Мне тоже кажется, что слишком запутано.
14. margo_m09 27.11.13 06:22 Сейчас в теме
Большой плюс автору, спасибо за идею))))))))))))))
15. yura1960 15.06.14 11:28 Сейчас в теме
Все гениальное - просто. Не скажу, что данное решение гениальное, но то, что оно упростит мне работу в следующем. Реально, что отказоустойчивость системы повышается!!!
Автору СПАСИБО!!!
16. TanyTany 24.11.16 01:18 Сейчас в теме
красиво, мне понравилось
Оставьте свое сообщение