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

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

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

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

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

Задача 1.5.

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

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

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

Списание себестоимости должно быть организовано по партиям, в зависимости от текущего значения принятого в учетной политике метода списания себестоимости (FIFO, по средней или LIFO). Учетная политика может меняться каждый день, ее изменение фиксируется соответствующим документом.

Считается, что документы задним числом не вводятся, но старые документы могут неоперативно перепроводится.

Необходимо построить отчет но продажам товаров за период и остаткам товара на указанную дату.

Продажи с 01.01.2010 по 31.03.2010

НоменклатураКол-воСебест-стьПродажаПрибыль
Куртка замшевая3300620320
Портсигар3305020
Доставка1100100

Прибыль рассчитывается как:

«Сумма продаж» — «Себестоимость» Остатки товаров па 01.01.2010

НоменклатураПартияКол-воСтоимость
Куртка замшевая4350
Прих. Накладная №12250
Прих. Накладная №22100
Портсигар665
Прих. Накладная №1550
Прих. Накладная №3115

Решение задачи оперативного учета 1С Специалист 8

Структура хранения данных

Первая задача — определится со структурой хранения данных:

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

Для хранения данных об остатках будем использовать регистр накопления «ОстаткиНоменклатуры» (тип — «Остатки»): измерения(разрезы) хранения у которого — «Номенклатура» и «Партия»(документ, которым была оприходован товар). В разрезе партий будет рассчитываться себестоимость товара.

Для хранения информации о продажах, нам потребуется регистр накопления «Продажи» (тип — «Обороты»). Измерение одно — «Номенклатура». Ресурса три — «Количество», «Сумма», «Себестоимость».  Решение хранить в регистре продаж «Себестоимость» достаточно спорное. В принципе, в вышеуказанном отчете можно было соединять два регистра для получения информации. Однако, я считаю, что скорость и простота получения информации должно оцениваться выше, чем место на диске.

регистры оперативного учета

Списание себестоимости должно быть организовано по партиям, в зависимости от текущего значения принятого в учетной политике метода списания себестоимости (FIFO, по средней или LIFO). Учетная политика может меняться каждый день, ее изменение фиксируется соответствующим документом.

Для хранения настройки будем использовать регистр сведений «МетодСписанияТоваров», с периодичностью — один день.  На закладке Данные укажем только ресурс — МетодСписания, а измерением будет период установки настройки. Для установки значения регистра сведений используем документ «УстановкаМетодаСписания», у которого укажем единственный реквизит — МетодСписания. В обработке проведения укажем следующий код:

Движения.МетодСписанияТоваров.Записывать = Истина;
Движение = Движения.МетодСписанияТоваров.Добавить();
Движение.Период = Дата;
Движение.МетодСписания = МетодСписания;

Что бы понимать, какая номенклатура является услугой, сделаем у справочника реквизит «Услуга», тип — булево:

доставка номенклатуры

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

Для решения данной задачи нам понадобится два документ — приходная накладная и расходная накладные. Рассмотрим их подробнее:

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

С точки зрения поступления товара — тут всё просто. В документе необходимо указать в какое время, сколько товара и по какой стоимости пришло. Структура поступления такая:

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

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

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

Расходная накладная

Структура метаданных документа Расходная накладная — аналогичная приходной, его можно полностью скопировать. Но с обработкой проведения расходной накладной 1С для списания партий всё немного сложнее.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

КонецЦикла;

КонецЦикла;

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

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

 Отчеты

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

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

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

Продажи:

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

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

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

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

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

P.S. Наша компания предоставляет услуги по настройке, доработке и комплексному внедрению 1С. Закажите бесплатный расчет стоимости вашей задачи на странице Услуги 1С или по телефону +7 (499) 350 29 00.

Остались вопросы?

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

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

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

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

    Ответить

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

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

      Ответить

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

        Ответить

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

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

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

    Ответить

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

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

      Ответить

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

Ваш e-mail не будет опубликован. Обязательные поля помечены *


*