Пример решения задачи 1С Специалист по платформе — Оперативный учет
Ниже я приведу пример решения типовой задачи для аттестационного билета «1С Специалист по платформе».
Содержание
Условие задачи: оперативный учет
Задача 1.5.
Компания занимается оптовой торговлей. Поступление товаров отражается документом «Приходная накладная», продажа — «Расходная накладная». Помимо продажи товара могут оказываться дополнительные услуги, например, по доставке. И услуги, и товары указываются в одной табличной части.
Складской учет товаров не ведется.
При проведении расходной накладной при нехватке товара необходимо выдавать соответствующее предупреждение с указанием количества нехватки и не позволять проводить документ.
Если вы только начинаете программировать в 1С или просто хотите систематизировать свои знания - попробуйте Школу программирования 1С нашего друга Владимира Милькина. Пошаговые и понятные уроки даже для новичка с поддержкой учителя.
Попробуйте бесплатно по ссылке >>
Списание себестоимости должно быть организовано по партиям, в зависимости от текущего значения принятого в учетной политике метода списания себестоимости (FIFO, по средней или LIFO). Учетная политика может меняться каждый день, ее изменение фиксируется соответствующим документом.
Считается, что документы задним числом не вводятся, но старые документы могут неоперативно перепроводиться.
Необходимо построить отчет но продажам товаров за период и остаткам товара на указанную дату.
Продажи с 01.01.2010 по 31.03.2010
Номенклатура | Кол-во | Себест-сть | Продажа | Прибыль |
Куртка замшевая | 3 | 300 | 620 | 320 |
Портсигар | 3 | 30 | 50 | 20 |
Доставка | 1 | 100 | 100 |
Прибыль рассчитывается как:
«Сумма продаж» — «Себестоимость» Остатки товаров па 01.01.2010
Номенклатура | Партия | Кол-во | Стоимость |
Куртка замшевая | 4 | 350 | |
Прих. Накладная №1 | 2 | 250 | |
Прих. Накладная №2 | 2 | 100 | |
Портсигар | 6 | 65 | |
Прих. Накладная №1 | 5 | 50 | |
Прих. Накладная №3 | 1 | 15 |
Решение задачи оперативного учета 1С Специалист 8
Структура хранения данных
Первая задача — определиться со структурой хранения данных.
Лучше всего при решении любой задачи отталкиваться от требуемых отчетов. В нашем случае нам необходимо показать пользователю себестоимость товаров в разрезе приходных накладных и отобразить продажи за период.
Для хранения данных об остатках будем использовать регистр накопления «ОстаткиНоменклатуры» (тип — «Остатки»): измерения (разрезы) хранения у которого — «Номенклатура» и «Партия» (документ, которым был оприходован товар). В разрезе партий будет рассчитываться себестоимость товара.
Для хранения информации о продажах нам потребуется регистр накопления «Продажи» (тип — «Обороты»). Измерение одно — «Номенклатура». Ресурса три — «Количество», «Сумма», «Себестоимость». Решение хранить в регистре продаж «Себестоимость» достаточно спорное. В принципе, в вышеуказанном отчете можно было соединять два регистра для получения информации. Однако я считаю, что скорость и простота получения информации должны оцениваться выше, чем место на диске.
Списание себестоимости должно быть организовано по партиям, в зависимости от текущего значения принятого в учетной политике метода списания себестоимости (FIFO, по средней или LIFO). Учетная политика может меняться каждый день, ее изменение фиксируется соответствующим документом.
Для хранения настройки будем использовать регистр сведений «МетодСписанияТоваров» с периодичностью — один день. На закладке Данные укажем только ресурс — МетодСписания, а измерением будет период установки настройки. Для установки значения регистра сведений используем документ «УстановкаМетодаСписания», у которого укажем единственный реквизит — МетодСписания. В обработке проведения укажем следующий код:
Движения.МетодСписанияТоваров.Записывать = Истина; Движение = Движения.МетодСписанияТоваров.Добавить(); Движение.Период = Дата; Движение.МетодСписания = МетодСписания;
Чтобы понимать, какая номенклатура является услугой, сделаем у справочника реквизит «Услуга», тип — булево:
С хранением данных мы разобрались. Приступим к отражению хозяйственных операций с помощью Документов.
Для решения данной задачи нам понадобится два документ — приходная накладная и расходная накладные. Рассмотрим их подробнее:
Приходная накладная
С точки зрения поступления товара тут всё просто. В документе необходимо указать, в какое время, сколько товара и по какой стоимости пришло. Структура поступления такая:
//получение учетной политики МетодСписания = РегистрыСведений.МетодСписанияТоваров.ПолучитьПоследнее(Дата).МетодСписания; Средняя = МетодСписания = Перечисления.УчетнаяПолитика.Средняя; //запись движений Движения.ОстаткиНоменклатуры.Записывать = Истина; Для Каждого ТекСтрокаСписокНоменклатуры Из СписокНоменклатуры Цикл Если ТекСтрокаСписокНоменклатуры.Номенклатура.Услуга Тогда Продолжить; КонецЕсли; Движение = Движения.ОстаткиНоменклатуры.Добавить(); Движение.ВидДвижения = ВидДвиженияНакопления.Приход; Движение.Период = Дата; Движение.Номенклатура = ТекСтрокаСписокНоменклатуры.Номенклатура; Если Не Средняя Тогда // если метод списания средняя - не следует записывать документ партия Движение.Партия = Ссылка; КонецЕсли; Движение.Количество = ТекСтрокаСписокНоменклатуры.Количество; Движение.Сумма = ТекСтрокаСписокНоменклатуры.Сумма; КонецЦикла;
Следует обратить внимание на важный момент — если учетная политика установлена как «средняя», то не следует писать в регистр ссылку на текущий документ. Потом, при списании, у нас будет взята себестоимость в разрезе «пустой» партии, т.е. по средней.
Расходная накладная
Структура метаданных документа Расходная накладная аналогична приходной, его можно полностью скопировать. Но с обработкой проведения расходной накладной 1С для списания партий всё немного сложнее.
Прежде всего, необходимо установить управляемую блокировку на данные. Делается это с той целью, чтобы защитить прочитанные данные от изменения другими пользователями. Делается это с помощью объекта «БлокировкаДанных» следующим программным кодом:
Блокировка = Новый БлокировкаДанных; ЭлементБлокировки = Блокировка.Добавить("РегистрНакопления.ОстаткиНоменклатуры"); ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный; ЭлементБлокировки.ИсточникДанных = СписокНоменклатуры; ЭлементБлокировки.ИспользоватьИзИсточникаДанных("Номенклатура", "Номенклатура"); Блокировка.Заблокировать();
В качестве источника данных у нас будет использоваться табличная часть документа «СписокНоменклатуры».
Далее необходимо узнать, какой метод списания установлен для текущего периода:
МетодСписания = РегистрыСведений.МетодСписанияТоваров.ПолучитьПоследнее(Дата).МетодСписания; Если МетодСписания.Пустая()Тогда Сообщение = Новый СообщениеПользователю; Сообщение.Текст = "Не указан метод списания! Проведение не возможно"; Отказ = Истина; Возврат; КонецЕсли; Средняя = МетодСписания = Перечисления.УчетнаяПолитика.Средняя;
После определения метода списания определяем количество товара для списания и формируем движения:
Движения.ОстаткиНоменклатуры.Записывать = Истина; Движения.Продажи.Записывать=Истина; Движения.ОстаткиНоменклатуры.Записать(); Движения.Продажи.Записать(); Запрос = Новый Запрос("ВЫБРАТЬ | РасходнаяНакладнаяСписокНоменклатуры.Номенклатура КАК Номенклатура, | СУММА(РасходнаяНакладнаяСписокНоменклатуры.Количество) КАК Количество, | СУММА(РасходнаяНакладнаяСписокНоменклатуры.Сумма) КАК Сумма |ПОМЕСТИТЬ ВТ |ИЗ | Документ.РасходнаяНакладная.СписокНоменклатуры КАК РасходнаяНакладнаяСписокНоменклатуры |ГДЕ | РасходнаяНакладнаяСписокНоменклатуры.Ссылка = &Ссылка | |СГРУППИРОВАТЬ ПО | РасходнаяНакладнаяСписокНоменклатуры.Номенклатура | |ИНДЕКСИРОВАТЬ ПО Номенклатура |; | |//////////////////////////////////////////////////////////////////////////////// |ВЫБРАТЬ | ВТ.Номенклатура КАК Номенклатура, | ВТ.Количество КАК КоличествоВДокументе, | ВТ.Сумма КАК СуммаВДокументе, | ОстаткиНоменклатурыОстатки.Партия, | ЕСТЬNULL(ОстаткиНоменклатурыОстатки.КоличествоОстаток, 0) КАК КоличествоОстаток, | ЕСТЬNULL(ОстаткиНоменклатурыОстатки.СуммаОстаток, 0) КАК СуммаОстаток |ИЗ | ВТ КАК ВТ | ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиНоменклатуры.Остатки( | &МоментВремени, | Номенклатура В | (ВЫБРАТЬ | ВТ.Номенклатура | ИЗ | ВТ КАК ВТ)) КАК ОстаткиНоменклатурыОстатки | ПО ВТ.Номенклатура = ОстаткиНоменклатурыОстатки.Номенклатура | |УПОРЯДОЧИТЬ ПО | ОстаткиНоменклатурыОстатки.Партия.МоментВремени ВОЗР |ИТОГИ | МАКСИМУМ(КоличествоВДокументе), | МАКСИМУМ(СуммаВДокументе), | СУММА(КоличествоОстаток), | СУММА(СуммаОстаток) |ПО | Номенклатура"); Запрос.УстановитьПараметр("МоментВремени", МоментВремени()); Запрос.УстановитьПараметр("Ссылка",Ссылка); Если МетодСписания = Перечисления.УчетнаяПолитика.ЛИФО Тогда Запрос.Текст = СтрЗаменить(Запрос.Текст, "ВОЗР", "УБЫВ"); // если лифо - сортируем по УБЫВанию КонецЕсли; ВыборкаНоменклатура = Запрос.Выполнить().Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам); Пока ВыборкаНоменклатура.Следующий() Цикл Если НЕ ВыборкаНоменклатура.Номенклатура.Услуга и ВыборкаНоменклатура.КоличествоОстаток < ВыборкаНоменклатура.КоличествоВДокументе Тогда Сообщение = Новый СообщениеПользователю; Сообщение.Текст = "Не хватает " + Строка(ВыборкаНоменклатура.КоличествоВДокументе - ВыборкаНоменклатура.КоличествоОстаток) + " единиц номенклатуры " + ВыборкаНоменклатура.Номенклатура + ". Проведение невозможно."; Сообщение.Сообщить(); Отказ = Истина; КонецЕсли; Если Отказ Тогда Продолжить; КонецЕсли; ОсталосьСписать = ВыборкаНоменклатура.КоличествоВДокументе; ВыборкаДетЗаписи = ВыборкаНоменклатура.Выбрать(); Пока ВыборкаДетЗаписи.Следующий() И ОсталосьСписать <> 0 Цикл Если НЕ ВыборкаДетЗаписи.Номенклатура.Услуга Тогда КСписанию = Мин(ОсталосьСписать, ВыборкаДетЗаписи.КоличествоОстаток); Если Средняя Тогда СуммаСписания = ?(ВыборкаНоменклатура.КоличествоОстаток =КСписанию, ВыборкаНоменклатура.СуммаОстаток, ВыборкаНоменклатура.СуммаОстаток/ВыборкаНоменклатура.КоличествоОстаток * КСписанию); Иначе СуммаСписания = ?(ВыборкаДетЗаписи.КоличествоОстаток =КСписанию, ВыборкаДетЗаписи.СуммаОстаток, ВыборкаДетЗаписи.СуммаОстаток/ВыборкаДетЗаписи.КоличествоОстаток * КСписанию); КонецЕсли; НовоеДвижение = Движения.ОстаткиНоменклатуры.ДобавитьРасход(); НовоеДвижение.Период = Дата; НовоеДвижение.Регистратор = Ссылка; НовоеДвижение.Количество = КСписанию; НовоеДвижение.Номенклатура = ВыборкаДетЗаписи.Номенклатура; Если НЕ Средняя Тогда НовоеДвижение.Партия = ВыборкаДетЗаписи.Партия; КонецЕсли; НовоеДвижение.Сумма = СуммаСписания; КонецЕсли; НовоеДвижение = Движения.Продажи.Добавить(); НовоеДвижение.Активность = Истина; НовоеДвижение.Период = Дата; НовоеДвижение.Регистратор = Ссылка; НовоеДвижение.Номенклатура = ВыборкаДетЗаписи.Номенклатура; НовоеДвижение.Сумма = ВыборкаДетЗаписи.СуммаВДокументе; Если НовоеДвижение.Номенклатура.Услуга Тогда НовоеДвижение.Себестоимость = 0; НовоеДвижение.Количество = ВыборкаНоменклатура.КоличествоВДокументе; Иначе НовоеДвижение.Количество = КСписанию; НовоеДвижение.Себестоимость = СуммаСписания; ОсталосьСписать = ОсталосьСписать - КСписанию; КонецЕсли; КонецЦикла; КонецЦикла;
Тут необходимо отметить следующие моменты:
- В зависимости от метода списания мы меняем текст запроса с помощью следующей конструкции: Запрос.Текст = СтрЗаменить(Запрос.Текст, «ВОЗР», «УБЫВ»).
- Не забудьте проиндексировать поля временной таблицы, по которой будете соединять таблицы (ИНДЕКСИРОВАТЬ ПО Номенклатура).
- Не забудьте проверять значения в запросах на NULL с помощью конструкции ЕСТЬNULL. NULL может возникнуть при соединении с другими таблицами при отсутствии значения в присоединяемой таблице.
- Решение проблемы копеек: если количество списываемого товара по данной партии равно остатку под данной партии, то списать всю сумму. Это позволит избавиться от остатка от деления. В нашем примере: СуммаСписания = ?(ВыборкаНоменклатура.КоличествоОстаток = КСписанию, ВыборкаНоменклатура.СуммаОстаток, ВыборкаНоменклатура.СуммаОстаток/ВыборкаНоменклатура.КоличествоОстаток * КСписанию).
- Если не хватает какой-либо номенклатуры, мы устанавливаем параметр «Отказ» в значение «Истина», однако продолжаем движения по строкам документа, чтобы вывести все сообщения о нехватке товара.
- Количество товара проверяется только для товара, без учета услуг.
- В цикле мы списываем до тех пор, пока не погасили потребность из документа (ОсталосьСписать <> 0).
- Если списание производится «по средней», то НЕ указываем документ партии.
- Если списание производится «по средней», сумму необходимо брать из итоговой строки группировки.
Отчеты
С данной структурой регистров отчеты получаются элементарные:
Остатки товаров:
Продажи:
Скачать решение задачи оперативного учета 1С специалист по платформе
Скачать вышеописанное решение Вы можете по ссылке.
Я буду рад Вашей критике, вопросам и замечаниям в комментариях, спасибо!
Удачи при подготовке! 🙂
Если Вы начинаете изучать 1С программирование, рекомендуем наш бесплатный курс (не забудьте подписаться на YouTube — регулярно выходят новые видео):
К сожалению, мы физически не можем проконсультировать бесплатно всех желающих, но наша команда будет рада оказать услуги по внедрению и обслуживанию 1С. Более подробно о наших услугах можно узнать на странице Услуги 1С или просто позвоните по телефону +7 (499) 350 29 00. Мы работаем в Москве и области.
СПРОСИТЕ в комментариях!
Law_Of_Evi1:
В коде описаны следующие условия:
Если ТекСтрокаСписокНоменклатуры.Номенклатура.Услуга Тогда
Продолжить;
КонецЕсли;
Для того чтобы получить значение реквизита «услуга», если в табличной части документа будет сотня позиций будут сделаны 100 запросов(Или я ошибаюсь?). Не лучше ли изначально эти данные получить запросом и потом проверять в цикле, а не получать «через точку»?
Кирилл:
Да, обращение через точку будет медленнее, чем получить данные одним запросом. Но не значительно. Да и не разу не видел что бы экзаменатор снижал оценку за такую ошибку.
Можете провести замер, даже интересно узнать результат 🙂
Алексей:
Обращение к реквизиту через точку в цикле — очень грубая ошибка на экзамене!
OLAP:
Да ладно.. Радченко с Хрусталевой учат тому же в книжках.
Для Каждого ТекСтрокаПереченьНоменклатуры Из ПереченьНоменклатуры Цикл
Если ТекСтрокаПереченьНоменклатуры.Номенклатура.ВидНоменклатуры =
Перечисления.ВидыНоменклатуры.Материал Тогда
Аноним:
Радченко книжка для начинающих, с упрощенными примерами.
Не теоретик:
Это что значит? Если ты дорос до мидла, не забудь сжечь и проклянуть мои труды (С) Хрусталев?
Стас:
Здесь не те «точки». В случае «точек «товара, в запрос платфомрой добавляется весь справочник товара и соединяется с таблице в запросе, и реально запрос усложняется. Просто это скрыто от на уровне платформы.
Дмитрий:
Сравнили опу с пальцем. Здесь ТекСтрокаПереченьНоменклатуры — это строка таблицы значений, а не обращение к ссылочному типу через точку.
Володя:
Всё верно говорите. За такое руки отрывать надо.
Не теоретик:
Да вы что, серьезно? Представьте себе я руководитель успешного отдела 1С и пишу через точку, люблю использовать вложенные запросы вместо таблиц, а еще я не всегда использую СКД, когда речь о разработке отчета))) Если есть желание мне что-то доказать пишите сюда. с удовольствием подискутируем
Еще один руководитель:
Руководитель отдела по созданию техдолга?
Членоводитель:
У меня реально 25 см. Если вы хотите мне что то доказать о разработке отчета буду рад увидеть ваши фото.
Евгений:
Кирилл, здравствуйте! Возможно, для Вас это уже не актуально, но может быть полезно для других.
В коде есть ошибка, приводящая к искажению информации о продажах.
В процедуре обработки проведения Расходной накладной в цикле обхода партий (ВыборкаДетЗаписи) в регистр Продажи каждый раз пишется вся СуммаВДокументе. Если списание идёт с более чем одной партии, продажи сильно преувеличиваются.
Это движение нужно вынести в цикл обхода итогов.
Также, учитывая выбранный Вами метод решения, документ смены учётной политики, при изменении с ФИФО/ЛИФО на Среднюю, должен закрывать все остатки на реальных партиях и переносить их на «пустую». Иначе остатки в регистре будут «зависать» при сменах политики, а это грубая ошибка, с точки зрения условий экзамена.
Константин:
Будут не только зависать остатки по партиям, при изменении с ФИФО/ЛИФО на Среднюю, но и будут отрицательные остатки на пустой партии если поступлений (после смены) не было, а списания были.
Данный вариант решения задачи оценивается на «2-«.
?:
«…ВыборкаДетЗаписи) в регистр Продажи каждый раз пишется вся СуммаВДокументе…» — надо писать ее часть:
СуммаВДокументе/КоличествоВДокументе*кСписанию
Николай:
На мой взгляд по ресурсу себестоимость в регистре Продажи себестоимость всегда растет в плюс. Это не хорошо. На экзамене за это сильно снижают оценку.
Николай:
не верно написал. Регистр продажи имеет вид Обороты. Тогда верно.
ОЛьга:
Скачать решение дали…а пароли пользователей не дали. Круто
Владимир:
в Условии задачи сказано — «Считается, что документы задним числом не вводятся, но старые документы могут неоперативно перепроводиться.» Подскажите, на что это влияет при решении задачи?
Константин:
Ресурс Себестоимость в регистре Продажи использовать правильнее, получение данных для отчета эффективнее получать из одного регистра.
Татьяна:
Считаю, что в РН ОстаткиНоменклатуры ссылку на приходный документ, т.е. партию, необходимо записывать независимо от метода списания на момент прихода. Иначе никакого партионного учета не получится, если между приходом и расходом поменялся метод списания.
Аноним:
Более того, при смене учетной политики на значение «По средней» надо сворачивать все партии в одну (пустую или это будет документ «ПриказПоУчетнойПолитике») — иначе как в дальнейшем закрывать регистр ОстаткиНоменклатуры в ноль по всем измерениям.
Нуб2:
Дайте пароль для входа в решение, пожалуйста!
НиколайД:
пароль пустой. пользователь адм
?:
Кто нибудь знает, откуда подобный билет? все то же, портсигар куртка и доставка но условие изменено:
1. УчетнаяПолитика [LIFO FIFO] — по среднему нет — периодичность год
2. Документы не перепроводятся
3. ПриходнаяНакладная может быть введена позже Расходной
4. РасходнаяНакладная может продавать в минус по УчетнойПолитке.РазрешитьОтрицательныеОстатки — периодичность год
Из этих условий оказывается распределение по партиям при проведении Расходной не главное, а главное — при проведении ПриходнойНакладной она должна гасить отрицательные остатки по пустым партиям, образованным РасходнойНакладной при продаже товароов, не распределившихся по партиям (отрицательные остатки)
???
Аноним:
РЕБЯТА ПОМОГИТЕ ПЛИЗ РЕШАТЬ ЭТУ ЗАДАЧКУ В 1С
Необходимо реализовать в электронном виде схему ERD, в которой отразить товарный учет и механизм списания себестоимости в Компании. Кроме этого, в любом удобном для вас виде нужно подготовить словарь данных по созданной ERD
Аноним:
дайте пороль пж
Не теоретик:
Все эти экзамены — как сдача на права в РФ. После получения корочки, как криво кодили, так и продолжают это делать. те кто быстро качественно пишет (не всегда следуя рекомендациям 1С — да и не надо) и без спеца выдает хороший результат
Дмитрий:
Я что-то не понял про регистр Продажи в цикле детальных записей… НовоеДвижение.Сумма = ВыборкаДетЗаписи.СуммаВДокументе;
Получается сумма продажи документа будет проходить столько раз, сколько списывается по партиям… я проверил у себя в базе. Продали 3шт товара на 100 руб. Списываем по партиям 1шт + 2шт = две записи в регистре продажи по суммам документа 100 руб = на 200 рублей продали… а на самом деле на 100. Может чего-то не понимаю
Руст:
решение неверно