Пока готовился на спеца по платформе мной были решены многие задачи из сборника. Выкладываю свои решения по решению:
- Оперативных задач (23 задачи: 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 15, 17, 24, 26, 28, 31, 32, 36, 37, 40, 42, 45).
- Бухгалтерских задач (21 задача: 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 14, 15, 18, 23, 27, 29, 31, 32, 33, 35)
- Расчетных задач (24 задачи: 01, 02, 03, 04, 05, 06, 07, 09, 12, 13, 15, 17, 16, 17, 18, 19, 20, 21, 22, 23, 27, 35, 43, 45, 48)
- Бизнес задачи присутствуют.
Может, кому пригодится при подготовке в качестве учебного материала. Текстовки задач в архиве отсутсвуют, дабы не нарушать соглашение.
PS: После прорешивания сдал с первого раза.
Пример решения Задачи по Бухгалтерии:
Необходимо реализовать возможность ведения учета товаров в разрезе организаций, мест хранения и партий товаров. Подразумевается, что для каждой организации баланс будет формировать отдельно (каждая организация это отдельное юридическое лицо). Склады у организаций «общие» (привязки склада к конкретной организации нет, но товар может принадлежать только одной организации). Под партией товара понимается документ, регистрирующий его поступление.
Документ «Приходная накладная» реализует следующую проводку: Дт «Товары» — Km «Поставщики» на количество и сумму закупаемого товара.
В системе необходимо реализовать документ, который осуществлял бы перемещение товара между собственными организациями (с возможным изменением склада компании). Фактически подобное перемещение будет регистрировать сразу две операции: продажа товара поставщиком покупателю и покупка покупателем товара у поставщика. Регистрация этих операций будет осуществляться документом «КупляПродажа». В шапке документа (при его заполнении) указывается организация-покупатель, организация-поставщик, склад организации-покупателя и склад организации-поставщика.
Документ «КупляПродажа» реализует следующие проводки:
По организации-поставщику:
Дт «Прибыли и убытки» — Km «Товары» на количество сумму себестоимости. Себестоимость товара рассчитывается для каждой организации в разрезе партий и складов по каждой номенклатурной позиции.
Дт «Покупатели» — Km «Прибыли и убытки» на сумму в продажных ценах;
По организаиии-пуодавцу: Дт «Товары» — Km «Поставщики» на сумму закупаемого товара
Решение:
Не буду расписывать создание объектов. Сразу к делу.
Документ «Приходная накладная» модуль объекта:
Процедура ОбработкаПроведения(Отказ, Режим)
//Блокировки накладывать смысла нет, тут только увеличиваем остатки.
// регистр Проводки
Движения.Проводки.Записывать = Истина;
Движения.Проводки.Очистить();
Для Каждого ТекСтрокаСписокНоменклатуры Из СписокНоменклатуры Цикл
Движение = Движения.Проводки.Добавить();
Движение.СчетДт = ПланыСчетов.Управленческий.Товары;
Движение.СчетКт = ПланыСчетов.Управленческий.Поставщики;
Движение.Период = Дата;
Движение.Организация = Организация;
Движение.КоличествоДт = ТекСтрокаСписокНоменклатуры.Количество;
Движение.Сумма = ТекСтрокаСписокНоменклатуры.Сумма;
Движение.СубконтоДт[ПланыВидовХарактеристик.ВидыСубконто.Номенклатура] = ТекСтрокаСписокНоменклатуры.Номенклатура;
Движение.СубконтоДт[ПланыВидовХарактеристик.ВидыСубконто.Склад] = Склад;
Движение.СубконтоДт[ПланыВидовХарактеристик.ВидыСубконто.Партия] = Ссылка;
КонецЦикла;
КонецПроцедуры
Документ «Купля продажа» модуль объекта:
Процедура ОбработкаПроведения(Отказ, Режим)
//Накладываю блокировки
// Без них можно даже не идти на экзамен
Блокировка = Новый БлокировкаДанных;
ЭлементБлокировки = Блокировка.Добавить("РегистрБухгалтерии.Проводки");
ЭлементБлокировки.УстановитьЗначение("Организация", Поставщик);
ЭлементБлокировки.УстановитьЗначение("Счет", ПланыСчетов.Управленческий.Товары);
ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный;
Блокировка.Заблокировать();
// регистр Проводки
//Ставлю признак, что бы платформа сама записала движения в регистр
Движения.Проводки.Записывать = Истина;
//Делаю по старинке - сначала формирую остатки, потом делаю движения.
//Т.к. имеется условное проведение и в добавок присутствуют партии товаров.
//Запрос по остаткам в регистре бухгалтерии
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| КупляПродажаСписокНоменклатуры.Номенклатура КАК Номенклатура,
| Минимум(КупляПродажаСписокНоменклатуры.НомерСтроки) КАК НС,
| СУММА(КупляПродажаСписокНоменклатуры.Количество) КАК КолДок,
| СУММА(КупляПродажаСписокНоменклатуры.Сумма) КАК СумДок
|ПОМЕСТИТЬ Товары
|ИЗ
| Документ.КупляПродажа.СписокНоменклатуры КАК КупляПродажаСписокНоменклатуры
|ГДЕ
| КупляПродажаСписокНоменклатуры.Ссылка = &Ссылка
|
|СГРУППИРОВАТЬ ПО
| КупляПродажаСписокНоменклатуры.Номенклатура
|
|ИНДЕКСИРОВАТЬ ПО
| Номенклатура
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| Товары.Номенклатура КАК Номенклатура,
| Товары.НС КАК НС,
| Товары.КолДок КАК КолДок,
| Товары.СумДок КАК СумДок,
| ПроводкиОстатки.Субконто3 КАК Партия,
| ЕСТЬNULL(ПроводкиОстатки.КоличествоОстаток, 0) КАК КолОст,
| ЕСТЬNULL(ПроводкиОстатки.СуммаОстаток, 0) КАК СумОст
|ИЗ
| Товары КАК Товары
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрБухгалтерии.Проводки.Остатки(
| &МоментВремени,
| Счет = &СчетТовары,
| &МассивСубконто,
| Организация = &Организация
| И Субконто2 = &СкладПоставщика
| И Субконто1 В
| (ВЫБРАТЬ
| Товары.Номенклатура
| ИЗ
| Товары КАК Товары)) КАК ПроводкиОстатки
| ПО Товары.Номенклатура = ПроводкиОстатки.Субконто1
|
|УПОРЯДОЧИТЬ ПО
| ПроводкиОстатки.Субконто3.МоментВремени
|ИТОГИ
| МАКСИМУМ(НС),
| МАКСИМУМ(КолДок),
| МАКСИМУМ(СумДок),
| СУММА(КолОст)
|ПО
| Номенклатура";
//Работаю только с теми видами субконто, которые мне необходимы в задаче
// Добавлю себе +. Что бы лишних вопросов не было
МассивСубконто = Новый Массив;
МассивСубконто.Добавить(ПланыВидовХарактеристик.ВидыСубконто.Номенклатура);
МассивСубконто.Добавить(ПланыВидовХарактеристик.ВидыСубконто.Склад);
МассивСубконто.Добавить(ПланыВидовХарактеристик.ВидыСубконто.Партия);
//Параметры запроса
Запрос.УстановитьПараметр("МассивСубконто", МассивСубконто);
Если Режим = РежимПроведенияДокумента.Оперативный Тогда
Движения.Проводки.Записать();
Запрос.УстановитьПараметр("МоментВремени", Неопределено);
Иначе
Запрос.УстановитьПараметр("МоментВремени", МоментВремени());
КонецЕсли;
Запрос.УстановитьПараметр("Организация", Поставщик);
Запрос.УстановитьПараметр("СкладПоставщика", СкладПоставщика);
Запрос.УстановитьПараметр("Ссылка", Ссылка);
Запрос.УстановитьПараметр("СчетТовары", ПланыСчетов.Управленческий.Товары);
Результат = Запрос.Выполнить();
//Обхожу по группировкам
// и создаю наборы движений
ВыборкаНоменклатура = Результат.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
СуммаПродажи = 0;
Пока ВыборкаНоменклатура.Следующий() Цикл
Если ВыборкаНоменклатура.КолОст < ВыборкаНоменклатура.КолДок Тогда
Отказ = Истина;
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Недостаточно товара: " + ВыборкаНоменклатура.Номенклатура + " на складе " + СкладПоставщика + ". В наличии " + ВыборкаНоменклатура.КолОст + " ед.";
Сообщение.Поле = "СписокНоменклатуры[" + (ВыборкаНоменклатура.НС - 1) + "].Количество";
Сообщение.УстановитьДанные(ЭтотОбъект);
Сообщение.Сообщить();
КонецЕсли;
Если Отказ Тогда
Продолжить;
КонецЕсли;
Выборка = ВыборкаНоменклатура.Выбрать();
СписатьВсего = ВыборкаНоменклатура.КолДок;
Пока Выборка.Следующий() И СписатьВсего > 0 Цикл
Списать = Мин(СписатьВсего, Выборка.КолОст);
Если Списать = Выборка.КолОст Тогда
Себестоимость = Выборка.СумОст;
Иначе
Себестоимость = Списать * Выборка.СумОст / Выборка.КолОст;
КонецЕсли;
Движение = Движения.Проводки.Добавить();
Движение.СчетДт = ПланыСчетов.Управленческий.ПрибылиУбытки;
Движение.СчетКт = ПланыСчетов.Управленческий.Товары;
Движение.Период = Дата;
Движение.Организация = Поставщик;
Движение.КоличествоКт = Списать;
Движение.Сумма = Себестоимость;
Движение.СубконтоДт[ПланыВидовХарактеристик.ВидыСубконто.Покупатель] = Покупатель;
Движение.СубконтоКт[ПланыВидовХарактеристик.ВидыСубконто.Номенклатура] = Выборка.Номенклатура;
Движение.СубконтоКт[ПланыВидовХарактеристик.ВидыСубконто.Склад] = СкладПоставщика;
Движение.СубконтоКт[ПланыВидовХарактеристик.ВидыСубконто.Партия] = Выборка.Партия;
СписатьВсего = СписатьВсего - Списать;
КонецЦикла;
Движение = Движения.Проводки.Добавить();
Движение.СчетДт = ПланыСчетов.Управленческий.Товары;
Движение.СчетКт = ПланыСчетов.Управленческий.Поставщики;
Движение.Период = Дата;
Движение.Организация = Покупатель;
Движение.КоличествоДт = ВыборкаНоменклатура.КолДок;
Движение.Сумма = ВыборкаНоменклатура.СумДок;
Движение.СубконтоДт[ПланыВидовХарактеристик.ВидыСубконто.Номенклатура] = ВыборкаНоменклатура.Номенклатура;
Движение.СубконтоДт[ПланыВидовХарактеристик.ВидыСубконто.Склад] = СкладПокупателя;
Движение.СубконтоДт[ПланыВидовХарактеристик.ВидыСубконто.Партия] = Ссылка;
СуммаПродажи = СуммаПродажи + ВыборкаНоменклатура.СумДок;
КонецЦикла;
Если Не Отказ Тогда
Движение = Движения.Проводки.Добавить();
Движение.СчетДт = ПланыСчетов.Управленческий.Покупатели;
Движение.СчетКт = ПланыСчетов.Управленческий.ПрибылиУбытки;
Движение.Период = Дата;
Движение.Организация = Поставщик;
Движение.Сумма = СуммаПродажи;
Движение.СубконтоДт[ПланыВидовХарактеристик.ВидыСубконто.Покупатель] = Покупатель;
Движение.СубконтоКт[ПланыВидовХарактеристик.ВидыСубконто.Покупатель] = Покупатель;
КонецЕсли;
КонецПроцедуры
В *.dt по задачам бизнес-процессах ваш вариант кода не отработает корректно, если в конфигураторе в список пользователей будет добавлен имя пользователя, имени которого не добавлено в справочник ФЛ.
Показать
Правильнее оформить условие вот так:
(2) chilyagin,
Однако, отрабатывало корректно на 100%. И именно такой код дают при подготовке на спеца и при решении сквозной задачи.
К тому же читаем справку:
СправочникМенеджер.<Имя справочника> (CatalogManager.<Имя справочника>)
НайтиПоНаименованию (FindByDescription)
НайтиПоНаименованию(<Наименование>, <ТочноеСоответствие>, <Родитель>, <Владелец>)
Возвращаемое значение:
Тип: СправочникСсылка.<Имя справочника>; Неопределено.
Ссылка на найденный элемент справочника.
Если не существует ни одного элемента с требуемым наименованием, то будет возвращена пустая ссылка.
Если для справочника наименование не задано (длина = 0) и поиск выполняется по полному соответствию, то будет возвращено Неопределено.
СправочникСсылка.<Имя справочника> (CatalogRef.<Имя справочника>)
Пустая (IsEmpty)
Возвращаемое значение:
Тип: Булево.
Истина — ссылка не указывает ни на какой объект (пустая ссылка); Ложь — в противном случае.
Ваш код в данном контексте будет ошибочным, т.к. поиск производится по точному совпадению и ссылки справочника не существует, т.е. Неопределено.
(3)
И сколько человек получили сертификат «специалист» по платформе или бухучёту с этим кодом?
(4) white-mount, Не умничай. Проверил — да, действительно. Не задавался целью ставить под сомнение подготовительные курсы.
Вопросы:
1. Почему вы используете определение режима проведения — на экзамене это ошибка или нет?
2. При выводе нехватки товара вы выводите ссылку номенклатура (неявное обращение к базе), а надо представление. Или я ошибаюсь?
(6) 1. Лучше использовать определение режима. В некоторых задачах будет считаться ошибкой/недочетом неумение пользоваться этим свойством/методом. С другой стороны Вы теряете время на написание кода.
2. Используйте представление. Но и использование ссылок не будет ошибкой/недочетом, т.к. перед нами не стоит задачи по оптимизации кода.
(7) 1. Приведите, пожалуйста пример.
2. А не будет ли это запрос в цикле?
(8) 1. Смотрите в примерах и задачи в сборнике задач. Я сейчас не вспомню. Давно подготовку проходил.
2. Что именно? К использованию ссылок внутри конструкций цикла по выборке не придираются. Или мне повезло 🙂 Вы же не на эксперта идете сдавать. Или…?
Загрузил первую задачу по ОУ, пересчеты суммы строки, пересчет суммы документа при изменении табличных частей не нужно что ли делать?
(10) На сколько помню, в постановке задачи такого условия не было (ни в одной). Зачем придумывать дополнительную работу, тем более что время жестко ограничено?
Спасибо за решения. Сейчас как раз готовлюсь и так же решаю задачи по сборнику. Хорошо когда можно сравнить свой код с решениями других программистов.