1С: специалист по платформе. Решение задачи 2.23
Решение:
Для решения задачи задействуем следующие объекты:
1) ПВХ «Виды субконто».
- Заполняем типы значений характеристик и дополнительные значения характеристик.
- Согласно условиям задачи заводим предопределенные элементы «Сотрудника», «ДатаВозврата».
2) Дорабатываем план счетов.
- на закладке «субконто» заполняем тип субконто и устанавливаем значение субконто=2.
- Редактируем предопределенный счет «КредитыЗаймыВыданные».(добавляем 2 субконто).
3) Добавляем регистр бухгалтерии «Управленческий».
- Связываем его с планом счетов
- Добавляем ресурсы ( сумма)
- Выбираем регистраторы.
4) Не забываем о том, что в задачах бухгалтерского учета необходимо добавить документ, с помощью которого можно добавлять записи в регистр вручную. Назовем его «Ручная операция». Укажем, что он является регистратором нашего регистра.
Добавим форму. На форму вытащим реквизит Объект-движения-управленческий.
5) Документ «Выдача Займа.»
Процедура ОбработкаПроведения(Отказ, РежимПроведения)
Движения.Управленческий.Записывать = Истина;
Движения.Управленческий.Записать();
// БлокировкаДанных
Блокировка = Новый БлокировкаДанных;
ЭлементБлокировки = Блокировка.Добавить("РегистрБухгалтерии.Управленческий");
ЭлементБлокировки.УстановитьЗначение("Субконто1", Сотрудник);
ЭлементБлокировки.УстановитьЗначение("Счет", ПланыСчетов.Управленческий.КредитыИЗаймыВыданные);
ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный;
Блокировка.Заблокировать();
БудемШтрафовать = Ложь;
Запрос =Новый("Запрос");
Запрос.Текст ="ВЫБРАТЬ
| УправленческийОстатки.СуммаОстатокДт КАК Долг,
| УправленческийОстатки.Субконто2 КАК ПланируемаяДатаВозврата
|ИЗ
| РегистрБухгалтерии.Управленческий.Остатки(&ТочкаИтогов, Счет = &Счет, &мсубконто, Субконто1 = &Сотрудник) КАК УправленческийОстатки";
Запрос.УстановитьПараметр("Счет", ПланыСчетов.Управленческий.КредитыИЗаймыВыданные);
Запрос.УстановитьПараметр("Сотрудник",Сотрудник);
ТочкаИтогов =?(РежимПроведения = РежимПроведенияДокумента.Оперативный, Неопределено, Новый Граница(МоментВремени(),ВидГраницы.Исключая));
Запрос.УстановитьПараметр("ТочкаИтогов",ТочкаИтогов);
мсубконто = Новый("Массив");
мсубконто.Добавить( ПланыВидовХарактеристик.ВидыСубконто.Сотрудник);
мсубконто.Добавить( ПланыВидовХарактеристик.ВидыСубконто.ДатаВозврата);
Запрос.УстановитьПараметр("мсубконто",мсубконто);
Результат = Запрос.Выполнить();
Если Не Результат.Пустой() Тогда
Выборка = Результат.Выбрать();
Выборка.Следующий();
Если Выборка.Долг<> Сумма Тогда
Отказ = Истина;
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Проведение невозможно, сумма долга = "+ Выборка.Долг;
Сообщение.Сообщить();
КонецЕсли;
Если Выборка.ПланируемаяДатаВозврата< НачалоДня(Дата) И Выборка.Долг>1 Тогда
БудемШтрафовать = Истина;
КонецЕсли;
Иначе
Отказ=Истина;
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Проведение невозможно, сотрудник ничего не должен";
Сообщение.Сообщить();
КонецЕсли;
Если Не Отказ Тогда
Движение = Движения.Управленческий.Добавить();
Движение.СчетКт = ПланыСчетов.Управленческий.КредитыИЗаймыВыданные;
Движение.СчетДт = ПланыСчетов.Управленческий.Касса;
Движение.Период = Дата;
Движение.Сумма = Сумма;
Движение.СубконтоКт[ПланыВидовХарактеристик.ВидыСубконто.Сотрудник] = Сотрудник;
Движение.СубконтоКт[ПланыВидовХарактеристик.ВидыСубконто.ДатаВозврата] = Дата;
КонецЕсли;
// штраф
Если БудемШтрафовать и ДатаВозвратаШтрафа = Дата(1,1,1) Тогда
Отказ = Истина;
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Проведение невозможно, необходимо заполнить дату возврата штрафа";
Сообщение.Сообщить();
КонецЕсли;
Если БудемШтрафовать Тогда
Движение = Движения.Управленческий.Добавить();
Движение.СчетДт = ПланыСчетов.Управленческий.КредитыИЗаймыВыданные;
Движение.СчетКт = ПланыСчетов.Управленческий.ПрибылиУбытки;
Движение.Период = Дата;
Движение.Сумма = Сумма/100;
Движение.СубконтоДт[ПланыВидовХарактеристик.ВидыСубконто.Сотрудник] = Сотрудник;
Движение.СубконтоДт[ПланыВидовХарактеристик.ВидыСубконто.ДатаВозврата] = ДатаВозвратаШтрафа;
КонецЕсли;
КонецПроцедуры
6) Документ «Возврат Займа»
Процедура ОбработкаПроведения(Отказ, РежимПроведения)
Движения.Управленческий.Записывать = Истина;
Движения.Управленческий.Записать();
// БлокировкаДанных
Блокировка = Новый БлокировкаДанных;
ЭлементБлокировки = Блокировка.Добавить("РегистрБухгалтерии.Управленческий");
ЭлементБлокировки.УстановитьЗначение("Субконто1", Сотрудник);
ЭлементБлокировки.УстановитьЗначение("Счет", ПланыСчетов.Управленческий.КредитыИЗаймыВыданные);
ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный;
Блокировка.Заблокировать();
БудемШтрафовать = Ложь;
Запрос =Новый("Запрос");
Запрос.Текст ="ВЫБРАТЬ
| УправленческийОстатки.СуммаОстатокДт КАК Долг,
| УправленческийОстатки.Субконто2 КАК ПланируемаяДатаВозврата
|ИЗ
| РегистрБухгалтерии.Управленческий.Остатки(&ТочкаИтогов, Счет = &Счет, &мсубконто, Субконто1 = &Сотрудник) КАК УправленческийОстатки";
Запрос.УстановитьПараметр("Счет", ПланыСчетов.Управленческий.КредитыИЗаймыВыданные);
Запрос.УстановитьПараметр("Сотрудник",Сотрудник);
ТочкаИтогов =?(РежимПроведения = РежимПроведенияДокумента.Оперативный, Неопределено, Новый Граница(МоментВремени(),ВидГраницы.Исключая));
Запрос.УстановитьПараметр("ТочкаИтогов",ТочкаИтогов);
мсубконто = Новый("Массив");
мсубконто.Добавить( ПланыВидовХарактеристик.ВидыСубконто.Сотрудник);
мсубконто.Добавить( ПланыВидовХарактеристик.ВидыСубконто.ДатаВозврата);
Запрос.УстановитьПараметр("мсубконто",мсубконто);
Результат = Запрос.Выполнить();
Если Не Результат.Пустой() Тогда
Выборка = Результат.Выбрать();
Выборка.Следующий();
Если Выборка.Долг<> Сумма Тогда
Отказ = Истина;
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Проведение невозможно, сумма долга = "+ Выборка.Долг;
Сообщение.Сообщить();
КонецЕсли;
Если Выборка.ПланируемаяДатаВозврата< НачалоДня(Дата) И Выборка.Долг>1 Тогда
БудемШтрафовать = Истина;
КонецЕсли;
Иначе
Отказ=Истина;
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Проведение невозможно, сотрудник ничего не должен";
Сообщение.Сообщить();
КонецЕсли;
Если Не Отказ Тогда
Движение = Движения.Управленческий.Добавить();
Движение.СчетКт = ПланыСчетов.Управленческий.КредитыИЗаймыВыданные;
Движение.СчетДт = ПланыСчетов.Управленческий.Касса;
Движение.Период = Дата;
Движение.Сумма = Сумма;
Движение.СубконтоКт[ПланыВидовХарактеристик.ВидыСубконто.Сотрудник] = Сотрудник;
Движение.СубконтоКт[ПланыВидовХарактеристик.ВидыСубконто.ДатаВозврата] = ПланируемаяДатаВозврата;
КонецЕсли;
// штраф
Если БудемШтрафовать и ДатаВозвратаШтрафа = Дата(1,1,1) Тогда
Отказ = Истина;
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Проведение невозможно, необходимо заполнить дату возврата штрафа";
Сообщение.Сообщить();
КонецЕсли;
Если БудемШтрафовать Тогда
Движение = Движения.Управленческий.Добавить();
Движение.СчетДт = ПланыСчетов.Управленческий.КредитыИЗаймыВыданные;
Движение.СчетКт = ПланыСчетов.Управленческий.ПрибылиУбытки;
Движение.Период = Дата;
Движение.Сумма = Сумма/100;
Движение.СубконтоДт[ПланыВидовХарактеристик.ВидыСубконто.Сотрудник] = Сотрудник;
Движение.СубконтоДт[ПланыВидовХарактеристик.ВидыСубконто.ДатаВозврата] = ДатаВозвратаШтрафа;
КонецЕсли;
КонецПроцедуры
7) Отчет.
Потребовалось соединение 2-х таблиц
ВЫБРАТЬ
Выдача.СубконтоДт1 КАК Сотрудник,
Выдача.СуммаОборот КАК СуммаЗайма,
Выдача.СубконтоДт2 КАК ПланируемаяДатаВозвращения,
Возвраты.ПериодДень КАК РеальнаяДатаВозвращения,
ВЫБОР
КОГДА Выдача.СчетКт = ЗНАЧЕНИЕ(ПланСчетов.Управленческий.ПрибылиУбытки)
ТОГДА "V"
КОНЕЦ КАК ЯвляетсяШтрафом
ИЗ
РегистрБухгалтерии.Управленческий.ОборотыДтКт(&ДатаНачала, &ДатаОкончания, , СчетДт = &Счет, , , , ) КАК Выдача
ЛЕВОЕ СОЕДИНЕНИЕ РегистрБухгалтерии.Управленческий.ОборотыДтКт(, , Авто, СчетДт = &счетКасса, , СчетКт = &Счет, , ) КАК Возвраты
ПО Выдача.СубконтоДт1 = Возвраты.СубконтоКт1
И Выдача.СуммаОборот = Возвраты.СуммаОборот
УПОРЯДОЧИТЬ ПО
ПланируемаяДатаВозвращения
Я конечно всё понимаю, но Вы не могли бы объяснить почему тут ЕСТЬNULL?
а вот тут нету
(1) slazzy, благодарю за наблюдательность. В данном случае сумма не имеет смысла, так как не влияет на результат. В ближайшее время исправлю и постараюсь впредь так не делать)
(2) Вы похоже не совсем поняли суть моего вопроса
Зачем тут использовать ЕСТЬNULL?
И вот тут аналогично
Показать
Группировать таблицу остатков не надо, она уже сгруппирована.
(3) slazzy,
1) Я Вас понял насчет группировки, погорячился)
2) За замечание про ЕСТЬNUll отдельное спасибо, уже вошло в привычку все подряд ресурсы «изналлить» на всякий случай. В этом случае естественно это необязательно так как нет соединений таблиц, что могло бы привести к появлению «null».
3) Еще исправил ошибку в документе «Возврат займа»
Если результат запроса пустой добавил
Отказ=Истина;
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = «Проведение невозможно, сотрудник ничего не должен»;
Сообщение.Сообщить();
КонецЕсли;
А почему только одна? И почему именно эта?
Мы как-то тут разбаловались и привыкли, что народ сразу скопом решения выкладывает.
(5) baton_pk, 7
Если имеете в виду исправленную ошибку, то где я написал что одна? Почему именно эта- наверное потому что ее я обнаружил.
Если у Вас имеется конструктивная критика, то не стесняйтесь критикуйте. буду благодарен.
(6)
Я не про ошибку, я про публикацию вообще. Почему только одна задача и почему именно эта??? Тут народ выкладывает решения сразу если не всех, то гораздо большего количества задач.
Замечание касательно 5) пункта решения.
После условия
в случае БудемШтрафовать = ИСТИНА будет зачем-то выполняться следующий блок,
даже если Отказ = ИСТИНА
(7) baton_pk, Это ж я как лучше хочу, выложу одно задание, народ покритикует, я в следующей задаче учту и исправлюсь. А именно эта просто потому что эта последняя что я решал.
(8) fancy, Вы правы, в случае Отказ = ИСТИНА незачем даже выполнять этот блок.
теперь по поводу того же ISNULL
Показать
вот тут
Наоборот нужен ISNULL
А вот тут
Неплохо бы сделать ветку ИНАЧЕ. Иначе если Счет не ПрибылиУбытки, то значение будет null
Я в задачу не вникал, мне лень 🙂 но мне кажется странным соединение по сумме
(11) slazzy, насчет «Null» в отчете, я не в курсе зачем ISNULL запросе в этом случае, ведь даже если получится «Null» я его не сравниваю и не складываю с другими значениями, если можно объясните как может возникнуть ошибка?
насчет соединения по сумме, то еще раз перепроверил все нормально, без этого результат запроса будет задваиваться, если займов выдано и погашено 2.
В документе «Возврат займа» нашел еще одну ошибку, надеюсь последнюю), нужно:
Движение.СубконтоКт[ПланыВидовХарактеристик.ВидыСубконто.ДатаВозврата] = Выборка.ПланируемаяДатаВозврата;
вместо
Движение.СубконтоКт[ПланыВидовХарактеристик.ВидыСубконто.ДатаВозврата] = Выборка.Дата;
(12)
Ошибки в принципе не будет. Это просто нуу как бы правило хорошего тона в общем случае избавляться от потенциальных NULL при соединениях. Но в целом никаких ошибок быть не должно.