Закажите бесплатный расчет стоимости вашей задачи по 1С!
Перезвоним за 10 минут!

Пример решения задачи 1С Специалист по платформе — Оперативный учет

Ниже я приведу пример решения типовой задачи для аттестационного билета «1С Специалист по платформе».

Приходная накладная

Условие задачи: оперативный учет

Задача 1.5.

Компания занимается оптовой торговлей. Поступление товаров отражается документом «Приходная накладная», продажа — «Расходная накладная». Помимо продажи товара могут оказываться дополнительные услуги, например, по доставке. И услуги, и товары указываются в одной табличной части.

Складской учет товаров не ведется.

При проведении расходной накладной при нехватке товара необходимо выдавать соответствующее предупреждение с указанием количества нехватки и не позволять проводить документ.

Списание себестоимости должно быть организовано по партиям, в зависимости от текущего значения принятого в учетной политике метода списания себестоимости (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С для списания партий всё немного сложнее.

Получите 267 видеоуроков по 1С бесплатно:

партии товара

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

Блокировка = Новый БлокировкаДанных;
ЭлементБлокировки = Блокировка.Добавить("РегистрНакопления.ОстаткиНоменклатуры");
ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный;
ЭлементБлокировки.ИсточникДанных = СписокНоменклатуры;
ЭлементБлокировки.ИспользоватьИзИсточникаДанных("Номенклатура", "Номенклатура");
Блокировка.Заблокировать();

В качестве источника данных у нас будет использоваться табличная часть документа «СписокНоменклатуры».

Далее необходимо узнать, какой метод списания установлен для текущего периода:

МетодСписания = РегистрыСведений.МетодСписанияТоваров.ПолучитьПоследнее(Дата).МетодСписания;

Если МетодСписания.Пустая()Тогда
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Не указан метод списания! Проведение не возможно";
Отказ = Истина;
Возврат;
КонецЕсли;

Средняя = МетодСписания = Перечисления.УчетнаяПолитика.Средняя;

После определения метода списания определяем количество товара для списания и формируем движения:

Движения.ОстаткиНоменклатуры.Записывать = Истина;
Движения.Продажи.Записывать=Истина;

Движения.ОстаткиНоменклатуры.Записать();
Движения.Продажи.Записать();

Запрос = Новый Запрос("ВЫБРАТЬ
| РасходнаяНакладнаяСписокНоменклатуры.Номенклатура КАК Номенклатура,
| СУММА(РасходнаяНакладнаяСписокНоменклатуры.Количество) КАК Количество,
| СУММА(РасходнаяНакладнаяСписокНоменклатуры.Сумма) КАК Сумма
|ПОМЕСТИТЬ ВТ
|ИЗ
| Документ.РасходнаяНакладная.СписокНоменклатуры КАК РасходнаяНакладнаяСписокНоменклатуры
|ГДЕ
| РасходнаяНакладнаяСписокНоменклатуры.Ссылка = &Ссылка
|
|СГРУППИРОВАТЬ ПО
| РасходнаяНакладнаяСписокНоменклатуры.Номенклатура
|
|ИНДЕКСИРОВАТЬ ПО Номенклатура
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ВТ.Номенклатура КАК Номенклатура,
| ВТ.Количество КАК КоличествоВДокументе,
| ВТ.Сумма КАК СуммаВДокументе,
| ОстаткиНоменклатурыОстатки.Партия,
| ЕСТЬNULL(ОстаткиНоменклатурыОстатки.КоличествоОстаток, 0) КАК КоличествоОстаток,
| ЕСТЬNULL(ОстаткиНоменклатурыОстатки.СуммаОстаток, 0) КАК СуммаОстаток
|ИЗ
| ВТ КАК ВТ
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиНоменклатуры.Остатки(
| &МоментВремени,
| Номенклатура В
| (ВЫБРАТЬ
| ВТ.Номенклатура
| ИЗ
| ВТ КАК ВТ)) КАК ОстаткиНоменклатурыОстатки
| ПО ВТ.Номенклатура = ОстаткиНоменклатурыОстатки.Номенклатура
|
|УПОРЯДОЧИТЬ ПО
| ОстаткиНоменклатурыОстатки.Партия.МоментВремени ВОЗР
|ИТОГИ
| МАКСИМУМ(КоличествоВДокументе),
| МАКСИМУМ(СуммаВДокументе),
| СУММА(КоличествоОстаток),
| СУММА(СуммаОстаток)
|ПО
| Номенклатура");

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

Если МетодСписания = Перечисления.УчетнаяПолитика.ЛИФО Тогда
Запрос.Текст = СтрЗаменить(Запрос.Текст, "ВОЗР", "УБЫВ"); // если лифо - сортируем по УБЫВанию
КонецЕсли;

ВыборкаНоменклатура = Запрос.Выполнить().Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);

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

Если НЕ ВыборкаНоменклатура.Номенклатура.Услуга и ВыборкаНоменклатура.КоличествоОстаток < ВыборкаНоменклатура.КоличествоВДокументе Тогда
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Не хватает " + Строка(ВыборкаНоменклатура.КоличествоВДокументе - ВыборкаНоменклатура.КоличествоОстаток) + " единиц номенклатуры " + ВыборкаНоменклатура.Номенклатура + ". Проведение невозможно.";
Сообщение.Сообщить();
Отказ = Истина;
КонецЕсли;

Если Отказ Тогда
Продолжить;
КонецЕсли;

ОсталосьСписать = ВыборкаНоменклатура.КоличествоВДокументе;

ВыборкаДетЗаписи = ВыборкаНоменклатура.Выбрать();
Пока ВыборкаДетЗаписи.Следующий() И ОсталосьСписать <> 0 Цикл

Если НЕ ВыборкаДетЗаписи.Номенклатура.Услуга Тогда

КСписанию = Мин(ОсталосьСписать, ВыборкаДетЗаписи.КоличествоОстаток);

Если Средняя Тогда
СуммаСписания = ?(ВыборкаНоменклатура.КоличествоОстаток =КСписанию,
ВыборкаНоменклатура.СуммаОстаток,
ВыборкаНоменклатура.СуммаОстаток/ВыборкаНоменклатура.КоличествоОстаток * КСписанию);
Иначе
СуммаСписания = ?(ВыборкаДетЗаписи.КоличествоОстаток =КСписанию,
ВыборкаДетЗаписи.СуммаОстаток,
ВыборкаДетЗаписи.СуммаОстаток/ВыборкаДетЗаписи.КоличествоОстаток * КСписанию);
КонецЕсли;

НовоеДвижение = Движения.ОстаткиНоменклатуры.ДобавитьРасход();
НовоеДвижение.Период = Дата;
НовоеДвижение.Регистратор = Ссылка;
НовоеДвижение.Количество = КСписанию;
НовоеДвижение.Номенклатура = ВыборкаДетЗаписи.Номенклатура;
Если НЕ Средняя Тогда
НовоеДвижение.Партия = ВыборкаДетЗаписи.Партия;
КонецЕсли;
НовоеДвижение.Сумма = СуммаСписания;
КонецЕсли;

НовоеДвижение = Движения.Продажи.Добавить();
НовоеДвижение.Активность = Истина;
НовоеДвижение.Период = Дата;
НовоеДвижение.Регистратор = Ссылка;
НовоеДвижение.Номенклатура = ВыборкаДетЗаписи.Номенклатура;
НовоеДвижение.Сумма = ВыборкаДетЗаписи.СуммаВДокументе;

Если НовоеДвижение.Номенклатура.Услуга Тогда
НовоеДвижение.Себестоимость = 0;
НовоеДвижение.Количество = ВыборкаНоменклатура.КоличествоВДокументе;
Иначе
НовоеДвижение.Количество = КСписанию;
НовоеДвижение.Себестоимость = СуммаСписания;
ОсталосьСписать = ОсталосьСписать - КСписанию;
КонецЕсли;

КонецЦикла;

КонецЦикла;

Тут необходимо отметить следующие моменты:

  1. В зависимости от метода списания мы меняем текст запроса с помощью следующей конструкции: Запрос.Текст = СтрЗаменить(Запрос.Текст, «ВОЗР», «УБЫВ»).
  2. Не забудьте проиндексировать поля временной таблицы, по которой будете соединять таблицы (ИНДЕКСИРОВАТЬ ПО Номенклатура).
  3. Не забудьте проверять значения в запросах на NULL с помощью конструкции ЕСТЬNULL. NULL может возникнуть при соединении с другими таблицами при отсутствии значения в присоединяемой таблице.
  4. Решение проблемы копеек: если количество списываемого товара по данной партии равно остатку под данной партии, то списать всю сумму. Это позволит избавиться от остатка от деления. В нашем примере: СуммаСписания = ?(ВыборкаНоменклатура.КоличествоОстаток = КСписанию, ВыборкаНоменклатура.СуммаОстаток, ВыборкаНоменклатура.СуммаОстаток/ВыборкаНоменклатура.КоличествоОстаток * КСписанию).
  5. Если не хватает какой-либо номенклатуры, мы устанавливаем параметр «Отказ» в значение «Истина», однако продолжаем движения по строкам документа, чтобы вывести все сообщения о нехватке товара.
  6. Количество товара проверяется только для товара, без учета услуг.
  7. В цикле мы списываем до тех пор, пока не погасили потребность из документа (ОсталосьСписать <> 0).
  8. Если списание производится «по средней», то НЕ указываем документ партии.
  9. Если списание производится «по средней», сумму необходимо брать из итоговой строки группировки.

 Отчеты

С данной структурой регистров отчеты получаются элементарные:

Остатки товаров:

остатки товаров

Продажи:

продажи товара

Скачать решение задачи оперативного учета 1С специалист по платформе

Скачать вышеописанное решение Вы можете по ссылке.

Я буду рад Вашей критике, вопросам и замечаниям в комментариях, спасибо!

Удачи при подготовке! 🙂

Если Вы начинаете изучать 1С программирование, рекомендуем наш бесплатный курс (не забудьте подписаться на YouTube — регулярно выходят новые видео):

К сожалению, мы физически не можем проконсультировать бесплатно всех желающих, но наша команда будет рада оказать услуги по внедрению и обслуживанию 1С. Более подробно о наших услугах можно узнать на странице Услуги 1С или просто позвоните по телефону +7 (499) 350 29 00. Мы работаем в Москве и области.
Остались вопросы?

СПРОСИТЕ в комментариях!

Комментариев: 8 на “Пример решения задачи 1С Специалист по платформе — Оперативный учет
  1. В коде описаны следующие условия:

    Если ТекСтрокаСписокНоменклатуры.Номенклатура.Услуга Тогда
    Продолжить;
    КонецЕсли;

    Для того чтобы получить значение реквизита «услуга», если в табличной части документа будет сотня позиций будут сделаны 100 запросов(Или я ошибаюсь?). Не лучше ли изначально эти данные получить запросом и потом проверять в цикле, а не получать «через точку»?

    Ответить

    • Да, обращение через точку будет медленнее, чем получить данные одним запросом. Но не значительно. Да и не разу не видел что бы экзаменатор снижал оценку за такую ошибку.

      Можете провести замер, даже интересно узнать результат 🙂

      Ответить

      • Обращение к реквизиту через точку в цикле — очень грубая ошибка на экзамене!

        Ответить

        • Да ладно.. Радченко с Хрусталевой учат тому же в книжках.
          Для Каждого ТекСтрокаПереченьНоменклатуры Из ПереченьНоменклатуры Цикл
          Если ТекСтрокаПереченьНоменклатуры.Номенклатура.ВидНоменклатуры =
          Перечисления.ВидыНоменклатуры.Материал Тогда

          Ответить

  2. Кирилл, здравствуйте! Возможно, для Вас это уже не актуально, но может быть полезно для других.

    В коде есть ошибка, приводящая к искажению информации о продажах.
    В процедуре обработки проведения Расходной накладной в цикле обхода партий (ВыборкаДетЗаписи) в регистр Продажи каждый раз пишется вся СуммаВДокументе. Если списание идёт с более чем одной партии, продажи сильно преувеличиваются.
    Это движение нужно вынести в цикл обхода итогов.

    Также, учитывая выбранный Вами метод решения, документ смены учётной политики, при изменении с ФИФО/ЛИФО на Среднюю, должен закрывать все остатки на реальных партиях и переносить их на «пустую». Иначе остатки в регистре будут «зависать» при сменах политики, а это грубая ошибка, с точки зрения условий экзамена.

    Ответить

    • Будут не только зависать остатки по партиям, при изменении с ФИФО/ЛИФО на Среднюю, но и будут отрицательные остатки на пустой партии если поступлений (после смены) не было, а списания были.

      Данный вариант решения задачи оценивается на «2-«.

      Ответить

  3. На мой взгляд по ресурсу себестоимость в регистре Продажи себестоимость всегда растет в плюс. Это не хорошо. На экзамене за это сильно снижают оценку.

    Ответить

    • не верно написал. Регистр продажи имеет вид Обороты. Тогда верно.

      Ответить

Добавить комментарий:

Ваш e-mail не будет опубликован.