1.    В базе данных есть две таблицы:

Справочник продукции (Productions)

 

Таблица отгрузок (Trade)

 

ProdID

Name

 

tDate

ProdID

Summa

1

Продукция 1

 

  01.01.2021          

1

10000

2

Продукция 2

 

15.01.2021

2

4000

3

Продукция 3

 

28.01.2021

2

2000

 

 

 

18.02.2021

1

3000

             

Необходимо написать запрос на 1С или SQL (по желанию) для выборки продукции, которая была отгружена за один период, и не отгружалась за другой. В приведенном примере, то что отгрузилось за январь 2021 и не отгрузилась за февраль 2021

Предложить два варианта запроса:

1.    С использованием подзапроса

 2. Без подзапросов, и без временных таблиц

 

 Пример результата:                          

 

ProdID

Name

1

Продукция 2

 

Решение 1:

ВЫБРАТЬ

              Продукция.ProdID КАК ProdID,

              Продукция.Name КАК Name

ПОМЕСТИТЬ Продукция

ИЗ

              &Продукция КАК Продукция

 

ИНДЕКСИРОВАТЬ ПО

              ProdID

;

 

////////////////////////////////////////////////////////////////////////////////

ВЫБРАТЬ

              ТаблицаОтгрузок.tDate КАК tDate,

              ТаблицаОтгрузок.ProdID КАК ProdID,

              ТаблицаОтгрузок.Summa КАК Summa

ПОМЕСТИТЬ ТаблицаОтгрузок

ИЗ

              &ТаблицаОтгрузок КАК ТаблицаОтгрузок

;

 

////////////////////////////////////////////////////////////////////////////////

ВЫБРАТЬ РАЗЛИЧНЫЕ

              НАЧАЛОПЕРИОДА(ТаблицаОтгрузок.tDate, МЕСЯЦ) КАК tDate,

              ТаблицаОтгрузок.ProdID КАК ProdID

ПОМЕСТИТЬ ПриведенныеПериодыОтгрузки

ИЗ

              ТаблицаОтгрузок КАК ТаблицаОтгрузок

 

ИНДЕКСИРОВАТЬ ПО

              tDate,

              ProdID

;

 

////////////////////////////////////////////////////////////////////////////////

УНИЧТОЖИТЬ ТаблицаОтгрузок

;

 

////////////////////////////////////////////////////////////////////////////////

ВЫБРАТЬ

              ПриведенныеПериодыОтгрузки.tDate КАК tDate,

              ПриведенныеПериодыОтгрузки.ProdID КАК ProdID

ПОМЕСТИТЬ ПодходящиеТовары

ИЗ

              ПриведенныеПериодыОтгрузки КАК ПриведенныеПериодыОтгрузки

                            ЛЕВОЕ СОЕДИНЕНИЕ ПриведенныеПериодыОтгрузки КАК ПриведенныеПериодыОтгрузкиДоп

                            ПО ПриведенныеПериодыОтгрузки.ProdID = ПриведенныеПериодыОтгрузкиДоп.ProdID

                                          И ПриведенныеПериодыОтгрузки.tDate <> ПриведенныеПериодыОтгрузкиДоп.tDate

ГДЕ

              ПриведенныеПериодыОтгрузкиДоп.tDate ЕСТЬ NULL

 

ИНДЕКСИРОВАТЬ ПО

              ProdID

;

 

////////////////////////////////////////////////////////////////////////////////

УНИЧТОЖИТЬ ПриведенныеПериодыОтгрузки

;

 

////////////////////////////////////////////////////////////////////////////////

ВЫБРАТЬ

              ПодходящиеТовары.ProdID КАК ProdID,

              Продукция.Name КАК Name

ИЗ

              ПодходящиеТовары КАК ПодходящиеТовары

                            ЛЕВОЕ СОЕДИНЕНИЕ Продукция КАК Продукция

 

                            ПО ПодходящиеТовары.ProdID = Продукция.ProdID

 

Решение 2.

ВЫБРАТЬ

              Продукция.ProdID КАК ProdID,

              Продукция.Name КАК Name

ПОМЕСТИТЬ Продукция

ИЗ

              &Продукция КАК Продукция

 

ИНДЕКСИРОВАТЬ ПО

              ProdID

;

 

////////////////////////////////////////////////////////////////////////////////

ВЫБРАТЬ

              ТаблицаОтгрузок.tDate КАК tDate,

              ТаблицаОтгрузок.ProdID КАК ProdID,

              ТаблицаОтгрузок.Summa КАК Summa

ПОМЕСТИТЬ ТаблицаОтгрузок

ИЗ

              &ТаблицаОтгрузок КАК ТаблицаОтгрузок

 

ИНДЕКСИРОВАТЬ ПО

              ProdID,

              tDate

;

 

 

///////////////////////////////////////////////////////////////////////////////

ВЫБРАТЬ РАЗЛИЧНЫЕ

              ТаблицаОтгрузок.ProdID КАК ProdID,

              Продукция.Name КАК Name

ИЗ

              ТаблицаОтгрузок КАК ТаблицаОтгрузок

                            ЛЕВОЕ СОЕДИНЕНИЕ Продукция КАК Продукция

                            ПО ТаблицаОтгрузок.ProdID = Продукция.ProdID

                            ЛЕВОЕ СОЕДИНЕНИЕ ТаблицаОтгрузок КАК ТаблицаОтгрузокДоп

                            ПО ТаблицаОтгрузок.ProdID = ТаблицаОтгрузокДоп.ProdID

                                          И (НАЧАЛОПЕРИОДА(ТаблицаОтгрузок.tDate, МЕСЯЦ) <> НАЧАЛОПЕРИОДА(ТаблицаОтгрузокДоп.tDate, МЕСЯЦ))

ГДЕ

 

              ТаблицаОтгрузокДоп.ProdID ЕСТЬ NULL

 

 

 

 

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

Таблица движения товара

 

cDate

ProdID

Count

10.01.2021

1

3

10.01.2021

2

2

12.01.2021

2

-1

15.01.2021

1

-1

       

Необходимо написать запрос на 1С или SQL (по желанию) который вернет среднее значение остатка товара за январь 2021 (с 1 по 31).


Решение

 

ВЫБРАТЬ

 

              ДОБАВИТЬКДАТЕ(&НачалоПериода, ДЕНЬ, aa.a * 1000 + bb.b * 100 + cc.c * 10 + dd.d) КАК Период

ПОМЕСТИТЬ ВсеДатыЗаПериод

ИЗ

              (ВЫБРАТЬ

                            0 КАК a

             

              ОБЪЕДИНИТЬ

             

              ВЫБРАТЬ

                            1

             

              ОБЪЕДИНИТЬ

             

              ВЫБРАТЬ

                            2

             

              ОБЪЕДИНИТЬ

             

              ВЫБРАТЬ

                            3

             

              ОБЪЕДИНИТЬ

             

              ВЫБРАТЬ

                            4

             

              ОБЪЕДИНИТЬ

             

              ВЫБРАТЬ

                            5

             

              ОБЪЕДИНИТЬ

             

              ВЫБРАТЬ

                            6

             

              ОБЪЕДИНИТЬ

             

              ВЫБРАТЬ

                            7

             

              ОБЪЕДИНИТЬ

             

              ВЫБРАТЬ

                            8

             

              ОБЪЕДИНИТЬ

             

              ВЫБРАТЬ

                            9) КАК aa

                            ПОЛНОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ

                                          0 КАК b

                           

                            ОБЪЕДИНИТЬ

                           

                            ВЫБРАТЬ

                                          1

                           

                            ОБЪЕДИНИТЬ

                           

                            ВЫБРАТЬ

                                          2

                           

                            ОБЪЕДИНИТЬ

                           

                            ВЫБРАТЬ

                                          3

                           

                            ОБЪЕДИНИТЬ

                           

                            ВЫБРАТЬ

                                          4

                           

                            ОБЪЕДИНИТЬ

                           

                            ВЫБРАТЬ

                                          5

                           

                            ОБЪЕДИНИТЬ

                           

                            ВЫБРАТЬ

                                          6

                           

                            ОБЪЕДИНИТЬ

                           

                            ВЫБРАТЬ

                                          7

                           

                            ОБЪЕДИНИТЬ

                           

                            ВЫБРАТЬ

                                          8

                           

                            ОБЪЕДИНИТЬ

                           

                            ВЫБРАТЬ

                                          9) КАК bb

                            ПО (ИСТИНА)

                            ПОЛНОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ

                                          0 КАК c

                           

                            ОБЪЕДИНИТЬ

                           

                            ВЫБРАТЬ

                                          1

                           

                            ОБЪЕДИНИТЬ

                           

                            ВЫБРАТЬ

                                          2

                           

                            ОБЪЕДИНИТЬ

                           

                            ВЫБРАТЬ

                                          3

                           

                            ОБЪЕДИНИТЬ

                           

                            ВЫБРАТЬ

                                          4

                           

                            ОБЪЕДИНИТЬ

                           

                            ВЫБРАТЬ

                                          5

                           

                            ОБЪЕДИНИТЬ

                           

                            ВЫБРАТЬ

                                          6

                           

                            ОБЪЕДИНИТЬ

                           

                            ВЫБРАТЬ

                                          7

                           

                            ОБЪЕДИНИТЬ

                           

                            ВЫБРАТЬ

                                          8

                           

                            ОБЪЕДИНИТЬ

                           

                            ВЫБРАТЬ

                                          9) КАК cc

                            ПО (ИСТИНА)

                            ПОЛНОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ

                                          0 КАК d

                           

                            ОБЪЕДИНИТЬ

                           

                            ВЫБРАТЬ

                                          1

                           

                            ОБЪЕДИНИТЬ

                           

                            ВЫБРАТЬ

                                          2

                           

                            ОБЪЕДИНИТЬ

                           

                            ВЫБРАТЬ

                                          3

                           

                            ОБЪЕДИНИТЬ

                           

                            ВЫБРАТЬ

                                          4

                           

                            ОБЪЕДИНИТЬ

                           

                            ВЫБРАТЬ

                                          5

                           

                            ОБЪЕДИНИТЬ

                           

                            ВЫБРАТЬ

                                          6

                           

                            ОБЪЕДИНИТЬ

                           

                            ВЫБРАТЬ

                                          7

                           

                            ОБЪЕДИНИТЬ

                           

                            ВЫБРАТЬ

                                          8

                           

                            ОБЪЕДИНИТЬ

                           

                            ВЫБРАТЬ

                                          9) КАК dd

                            ПО (ИСТИНА)

ГДЕ

              aa.a * 1000 + bb.b * 100 + cc.c * 10 + dd.d <= РАЗНОСТЬДАТ(&НачалоПериода, &КонецПериода, ДЕНЬ)

;

 

////////////////////////////////////////////////////////////////////////////////

ВЫБРАТЬ

              ТаблицаТоваров.cDate КАК cDate,

              ТаблицаТоваров.ProdID КАК ProdID,

              ТаблицаТоваров.Count КАК Count

ПОМЕСТИТЬ ТаблицаТоваров

ИЗ

              &ТаблицаТоваров КАК ТаблицаТоваров

ГДЕ

              ТаблицаТоваров.cDate МЕЖДУ &НачалоПериода И &КонецПериода

 

ИНДЕКСИРОВАТЬ ПО

              cDate,

              ProdID

;

 

////////////////////////////////////////////////////////////////////////////////

ВЫБРАТЬ

              ТаблицаТоваров.cDate КАК cDate,

              ТаблицаТоваров.ProdID КАК ProdID,

              ТаблицаТоваров.Count КАК ОборотТекущий,

              СУММА(ТаблицаТоваровДоп.Count) КАК ОборотПрошлыхПериодов

ПОМЕСТИТЬ ВрТ_ТекущиеОстатки

ИЗ

              ТаблицаТоваров КАК ТаблицаТоваров

                            ЛЕВОЕ СОЕДИНЕНИЕ ТаблицаТоваров КАК ТаблицаТоваровДоп

                            ПО (ТаблицаТоваровДоп.cDate < ТаблицаТоваров.cDate)

                                          И ТаблицаТоваров.ProdID = ТаблицаТоваровДоп.ProdID

 

СГРУППИРОВАТЬ ПО

              ТаблицаТоваров.cDate,

              ТаблицаТоваров.ProdID,

              ТаблицаТоваров.Count

;

 

////////////////////////////////////////////////////////////////////////////////

ВЫБРАТЬ

              ВрТ_ТекущиеОстатки.cDate КАК cDate,

              ВрТ_ТекущиеОстатки.ProdID КАК ProdID,

              ВрТ_ТекущиеОстатки.ОборотТекущий + ЕСТЬNULL(ВрТ_ТекущиеОстатки.ОборотПрошлыхПериодов, 0) КАК КонечныйОстаток

ПОМЕСТИТЬ ТекущиеОстатки

ИЗ

              ВрТ_ТекущиеОстатки КАК ВрТ_ТекущиеОстатки

 

ОБЪЕДИНИТЬ ВСЕ

 

ВЫБРАТЬ РАЗЛИЧНЫЕ

              &НачалоПериода,

              ТаблицаТоваров.ProdID,

              0

ИЗ

              ТаблицаТоваров КАК ТаблицаТоваров

;

 

////////////////////////////////////////////////////////////////////////////////

УНИЧТОЖИТЬ ВрТ_ТекущиеОстатки

;

 

////////////////////////////////////////////////////////////////////////////////

УНИЧТОЖИТЬ ТаблицаТоваров

;

 

////////////////////////////////////////////////////////////////////////////////

ВЫБРАТЬ

              ВсеДатыЗаПериод.Период КАК Период,

              ТекущиеОстатки.ProdID КАК ProdID,

              МАКСИМУМ(ТекущиеОстатки.cDate) КАК cDate

ПОМЕСТИТЬ ВрТ_УчетныеПериодыОстатков_Василий1

ИЗ

              ВсеДатыЗаПериод КАК ВсеДатыЗаПериод

                            ВНУТРЕННЕЕ СОЕДИНЕНИЕ ТекущиеОстатки КАК ТекущиеОстатки

                            ПО ВсеДатыЗаПериод.Период >= ТекущиеОстатки.cDate

 

СГРУППИРОВАТЬ ПО

              ВсеДатыЗаПериод.Период,

              ТекущиеОстатки.ProdID

;

 

////////////////////////////////////////////////////////////////////////////////

ВЫБРАТЬ

              ВрТ_УчетныеПериодыОстатков_Василий1.Период КАК Период,

              ВрТ_УчетныеПериодыОстатков_Василий1.ProdID КАК ProdID,

              ЕСТЬNULL(ТекущиеОстатки.КонечныйОстаток, 0) КАК КонечныйОстаток

ПОМЕСТИТЬ ВрТ_СводДанныеОстатков

ИЗ

              ВрТ_УчетныеПериодыОстатков_Василий1 КАК ВрТ_УчетныеПериодыОстатков_Василий1

                            ЛЕВОЕ СОЕДИНЕНИЕ ТекущиеОстатки КАК ТекущиеОстатки

                            ПО ВрТ_УчетныеПериодыОстатков_Василий1.ProdID = ТекущиеОстатки.ProdID

                                          И ВрТ_УчетныеПериодыОстатков_Василий1.cDate = ТекущиеОстатки.cDate

;

 

////////////////////////////////////////////////////////////////////////////////

ВЫБРАТЬ

              ВрТ_СводДанныеОстатков.ProdID КАК ProdID,

              СРЕДНЕЕ(ВрТ_СводДанныеОстатков.КонечныйОстаток) КАК КонечныйОстаток

ИЗ

              ВрТ_СводДанныеОстатков КАК ВрТ_СводДанныеОстатков

 

СГРУППИРОВАТЬ ПО

              ВрТ_СводДанныеОстатков.ProdID

 

 

3.    Дано:

 

JSON-строка

{

    "kkm_uuid""71a08f7c-1bb6-11e8-8351-f01fafd7431a",

    "staff_uuid""e4c5a037-92f6-11e7-8416-005056b34cfa",

    "customer_uuid""ac63a2fb-42dc-11e3-9038-00221965065c",

    "receipt": {

        "uuid""",

        "operation""presale",

        "add_bonus"true,

        "coupons": [

            

        ],

        "promokods": [

            

        ],

        "bonus""true",

        "products": [

            {

                "id": 1,

                "barcode": ""

            }

        ]

    }

}

 

Задача:

Необходимо выполнить проверку на заполненность обязательных полей:

kkm_uuid; staff_uuid; customer_uuid; receipt; operation; bonus; products; id; barcode

 

в сообщении вывести полный путь до поля, которое не заполнено.

 

 

 

Решение:

 

&НаСервере

Процедура TestНаСервере()

             

              //СтрокаJSON = ПолучитьТестовуюСтрокуJSON();

             

              //Вариант 1. Тестовый JSON сериализуется в объект 1с. Будем считать что так оно и будет всегда

              ЧтениеJSON = Новый ЧтениеJSON;

              ЧтениеJSON.УстановитьСтроку(СтрокаJSON);

              Попытка

                            СтруктураJSON = ПрочитатьJSON(ЧтениеJSON);

              Исключение

                            ОбщегоНазначенияКлиентСервер.СообщитьПользователю("Не удалось преобразовать JSON для чтения"+Символы.ПС+ОписаниеОшибки());

                            Возврат;

              КонецПопытки;              

             

              НачатьВалидациюПоСтруктуре(СтруктураJSON);

             

КонецПроцедуры           

 

&НаСервере

Процедура НачатьВалидациюПоСтруктуре(СтруктураJSON)

             

              СтруктураProducts = Новый Структура;

              СтруктураProducts.Вставить("id");

              СтруктураProducts.Вставить("barcode");

             

              СтруктураReceipt = Новый Структура;

              СтруктураReceipt.Вставить("operation");

              СтруктураReceipt.Вставить("bonus");

              СтруктураReceipt.Вставить("products", СтруктураProducts);           

             

              ПроверяемыеПоля = Новый Структура;

              ПроверяемыеПоля.Вставить("kkm_uuid");

              ПроверяемыеПоля.Вставить("staff_uuid");

              ПроверяемыеПоля.Вставить("customer_uuid");

              ПроверяемыеПоля.Вставить("receipt", СтруктураReceipt);

             

              ВалидацияСтруктурыРек(СтруктураJSON, ПроверяемыеПоля)

                                         

КонецПроцедуры           

 

&НаСервере

Процедура ВалидацияСтруктурыРек(ПроверяемаяСтруктура, ПроверяемыеПоля, ИмяРодительскойСтруктуры = "")

             

              #Если Клиент И Сервер Тогда

                            ПроверяемыеПоля = Новый Структура;  

              #КонецЕсли      

             

              Для Каждого пСтрока Из ПроверяемаяСтруктура Цикл

                           

                            Если (ТипЗнч(пСтрока.Значение) = Тип("Структура") ИЛИ ТипЗнч(пСтрока.Значение) = Тип("Массив")) И НеобходимоПроверятьПоле(пСтрока.Ключ, ПроверяемыеПоля) Тогда

                                         

                                          //Проверка структуры

                                          //СперваПроверяем что заполнена сама структура

                                          Если пСтрока.Значение.Количество() = 0 Тогда

                                                        СообщитьОНеЗаполненомПоле(пСтрока.Ключ, Истина, ИмяРодительскойСтруктуры);

                                                        Продолжить;

                                          КонецЕсли;                     

                                         

                                          //проверка вложенных полей

                                          КоллекцияПроверяемыхПолей = Неопределено;

                                          Если ПроверяемыеПоля.Свойство(пСтрока.Ключ, КоллекцияПроверяемыхПолей) И ТипЗнч(КоллекцияПроверяемыхПолей) = Тип("Структура") И КоллекцияПроверяемыхПолей.Количество() > 0 Тогда 

                                                       

                                                        ИмяРодительскойСтруктуры = ИмяРодительскойСтруктуры + ?(ПустаяСтрока(ИмяРодительскойСтруктуры), "", " -> ")    + пСтрока.Ключ;

                                                       

                                                        Если ТипЗнч(пСтрока.Значение) = Тип("Массив") Тогда

                                                                      

                                                                       //Массив структура

                                                                       Для Каждого пСтрокаМассив Из пСтрока.Значение Цикл

                                                                                     ВалидацияСтруктурыРек(пСтрокаМассив, КоллекцияПроверяемыхПолей, ИмяРодительскойСтруктуры);

                                                                       КонецЦикла;    

                                                                      

                                                        Иначе

                                                                      

                                                                      ВалидацияСтруктурыРек(пСтрока.Значение, КоллекцияПроверяемыхПолей, ИмяРодительскойСтруктуры);     

                                                                      

                                                        КонецЕсли;       

                                                       

                                          КонецЕсли;                                   

                                         

                            ИначеЕсли НеобходимоПроверятьПоле(пСтрока.Ключ, ПроверяемыеПоля) = Истина Тогда         

                                         

                                          //Простое поле

                                          Если Не ЗначениеЗаполнено(пСтрока.Значение) Тогда

                                                        СообщитьОНеЗаполненомПоле(пСтрока.Ключ, Ложь, ИмяРодительскойСтруктуры);

                                          КонецЕсли;                                   

                                         

                            КонецЕсли;       

                           

              КонецЦикла;    

             

КонецПроцедуры           

 

&НаСервере

Процедура СообщитьОНеЗаполненомПоле(ИмяПоля, ЭтоСтруктура, ИмяРодительскойСтруктуры)

             

              ШаблонТекстаСообщения = "%1 ""%2""";

              Если ЭтоСтруктура = Истина Тогда

                            ПредставлениеОшибкиТипКоллекции = "Не заполнена коллекция свойств";

              Иначе

                            ПредставлениеОшибкиТипКоллекции = "Не заполнено поле";

              КонецЕсли;

             

              ПолныйПутьПоля = ИмяРодительскойСтруктуры + ?(ПустаяСтрока(ИмяРодительскойСтруктуры), "", " -> ") + ИмяПоля;

             

              ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ШаблонТекстаСообщения, ПредставлениеОшибкиТипКоллекции, ПолныйПутьПоля);

ОбщегоНазначенияКлиентСервер.СообщитьПользователю(ТекстОшибки);                           

             

КонецПроцедуры

 

&НаСервере

Функция НеобходимоПроверятьПоле(ИмяКлюча, ПроверяемыеПоля)

             

              #Если Клиент И Сервер Тогда

                            ПроверяемыеПоля = Новый Структура;  

              #КонецЕсли      

             

              Возврат ПроверяемыеПоля.Свойство(ИмяКлюча) = Истина;

             

КонецФункции

 

 

 

 

4.    Документ ПоступлениеТоваров при проведении делает движения по 2 регистрам:

·       приход по регистру накопления ТоварыНаСкладах

·       расход по регистру накопления ЗаказыПоставщикам

Запись в регистр накопления ТоварыНаСкладах делается в рублях (Сумма) и в долларах (СуммаВал). Курс берется на дату партии.

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

Ниже представлена обработка проведения документа ПоступлениеТоваров.

 

Необходимо указать на ошибки и неоптимальные решения в процедуре проведения.

 

ВНИМАНИЕ, ТУТ ЗАЛОЖЕНО БОЛЕЕ 20 ОШИБОК И НЕОПТИМАЛЬНЫХ

РЕШЕНИЙ, необходимо найти минимум 15

Процедура ОбработкаПроведения(Отказ, РежимПроведения)

 

             

              Запрос = Новый Запрос;

              Запрос.Текст = "ВЫБРАТЬ

                             |            Товары.Номенклатура КАК Номенклатура,

                             |            Товары.Партия КАК Партия,

                             |            Товары.Количество КАК Количество,

                             |            Товары.Сумма КАК Сумма,

                             |            Заказы.КоличествоОстаток КАК КоличествоОстаток

                             |ИЗ

                             |            Документ.ПоступлениеТоваров.Товары КАК Товары

                             |ЛЕВОЕ СОЕДИНЕНИЕ

|РегистрНакопления.ЗаказыПоставщикам.Остатки(&Период, Контрагент = &Контрагент) КАК Заказы

                             |                           ПО Товары.Номенклатура = Заказы.Номенклатура

                             |                                         И Товары.Партия = Заказы.Партия

                             |ГДЕ

                             |            Товары.Ссылка = &Ссылка

                             |            И (Заказы.Номенклатура, Заказы.Партия) В

                             |                                         (ВЫБРАТЬ

                             |                                                       Товары.Номенклатура,

                             |                                                       Товары.Партия

                             |                                         ИЗ

                             |                                                       Документ. ПоступлениеТоваров.Товары КАК Товары

                             |                                         ГДЕ

                             |                                                       Товары.Ссылка = &Ссылка)

                             |ИТОГИ

                             |            СУММА(Количество),

                             |            СУММА(Сумма),

                             |            СУММА(КоличествоОстаток)

                             |ПО

                             |            Номенклатура,

                             |            Партия";

                                                           

              ВыборкаНоменклатура = Запрос.Выполнить().Выбрать();

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

                            Если ВыборкаНоменклатура.Количество > ВыборкаНоменклатура.КоличествоОстаток Тогда

                                          Сообщить("Количество в поступлении "

                                          +ВыборкаНоменклатура.Количество

+ " " + ВыборкаНоменклатура.Номенклатура.ЕдиницаИзмерения

                                          + " превышает остаток по заказам "

                                          +ВыборкаНоменклатура.КоличествоОстаток

+ " " + ВыборкаНоменклатура.Номенклатура.ЕдиницаИзмерения);

                            Иначе

                                          ВыборкаПартия = ВыборкаНоменклатура.Выбрать();

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

                                                         СуммаВал = СуммаВал

+ РегистрыСведений.КурсыВалют.ПолучитьПоследнее(

                                                         ВыборкаПартия.Партия.Дата

,Новый Структура("Валюта", Справочники.Валюты.НайтиПоНаименованию(«USD»)));

                                                        

                                                         Движение = РегистрыНакопления.ЗаказыПоставщикам.Добавить();

                                                         Движение.ВидДвижения = ВидДвиженияНакопления.Расход;

                                                         Движение.Период = Дата;

                                                         Движение.Номенклатура = ВыборкаПартия.Номенклатура;

                                                         Движение.Количество = ВыборкаПартия.Количество;                                                 

                                          КонецЦикла;

                                         

                                          Движение = Движения.ТоварыНаСкладах.Добавить();

                                          Движение.Период = Дата;

                                          Движение.Номенклатура = ВыборкаНоменклатура.Номенклатура;

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

                                          Движение.Сумма = ВыборкаНоменклатура.Сумма;

                                          Движение.СуммаВал = СуммаВал;

                                         

                            КонецЕсли;

              КонецЦикла;    

 

КонецПроцедуры

 

 

Решение:

11.     Ошибка. Нет установки параметров для запроса. 3 шт.

 

2.     Строка 12-15. СОЕДИНЕНИЕ РегистрНакопления.ЗаказыПоставщикам.

a.     Нельзя соединяться с виртуальными таблицами в запросе. Следовало бы использовать сначала чтение во временную таблицу.

3.     Строка 9. Заказы.КоличествоОстаток КАК КоличествоОстаток при левом соединении здесь надо использовать ЕСТЬNULL(, 0). Иначе потом при «ВыборкаНоменклатура.Количество > ВыборкаНоменклатура.КоличествоОстаток» будет исключение о приведении типов

4.     Строка 34. ВыборкаНоменклатура = Запрос.Выполнить().Выбрать(); Здесь не совсем не точность, скорее просто небольшая оптимизация.  Когда каждая мс выполнения дорога, лучше сначала проверять что РезультатЗапроса не пустой, а потом уже тащить с сервера выборку. Иначе получается, что тащится выборка с сервера, а там пусто.

5.     Строка 18. И (Заказы.Номенклатура, Заказы.Партия) . Это параметры вирт таблицы, так что нужно их и вынести в параметры, чем писать их в области ГДЕ. + Там еще и лишние записи будут до соедеинения, т.к.

6.     Строка 23. Документ. ПоступлениеТоваров.Товары – Тут еще раз делается запрос к таблице. Лучше ТЧ товары сначала сохранить в ВТ и потом к ней обращаться.

7.     Строка 37. Сообщить – это скорее устаревший метод, он не работает на УФ, лучше использовать ОбщегоНазначения.СообщитьПользователю. Результат и на ОФ и На УФ будет одинаковым.

8.     Строка 39, 43. ВыборкаНоменклатура.Номенклатура.ЕдиницаИзмерения обращение через точку вызовет запрос к СУБД. Там конечно есть, какое то кэширование серверных значений. Но раз уж тут получаются данные через запрос и там будет номенклатура, то лучше сразу перенести в запрос.

9.     В качестве не оптимальных решений можно так же указать отсутствие установленных БлокировокДанных. Но тут вопрос скорее конфигурации. Может в ней стоит автоматический режим. Может этот документ создается один раз в год и ночью когда никто не работает(хотя это поступление, так что врятли, так что из разряда фантастики)

10.  Строка 49-50.

a.     СуммаВал = СуммаВал         +РегистрыСведений.КурсыВалют.ПолучитьПоследнее()

b.     Это тот же запрос, да еще к вирт. таблице, да еще и вызывается в цикле.  Надо переносить в основной запрос. Хотя бы как пакет, а еще лучше рассчитывать суммуВал для каждой строки в запросе.

11.  Строка 52. Справочники.Валюты.НайтиПоНаименованию(«USD»)  - это в цикле вызывается, и всегда возвращает одно и тоже значение. Лучше перенести поиск до цикла и потом просто его передавать

12.  Строка 52. Справочники.Валюты.НайтиПоНаименованию(«USD»)  - так же тут идет поиск по наименованию, что не верно. Лучше искать по коду. Или по гуиду. Или вообще завести как предопределенное значение, если его нет в конфе.

13.  Строка 52 - Новый Структура("Валюта", …)  тут еще момент, если не учитывать п.9 и п.10. То такую структуру лучше объявить до цикла и потом передавать её в функцию и если надо менять параметр. Тут параметр всегда один, так что лучше и все структуру один раз объявить и заполнить

14.  Строка 54, 61. Движение = РегистрыНакопления.ЗаказыПоставщикам  - перед записью движений надо очищать движения. Т.к. в случае перепроведения коллекция не очистится. Так же, сама коллекция движений явно не записывается, и не установлен флаг Записывать.

15.  Строка 49 – СуммаВал  = Сумма Вал  - Во первых, не инициализируется переменная. Во вторых – изза того что она не инициализацируется в выборке по номенклатуре её значение не «сбрасывается». К тому же, если цикл  ВыборкаПартия.Следующий() будет пустой, то наверное будет ошибка(вот точно не помню, по идее там неопределено будет, а приведется ли он к 0, не пробовал).

16.  Строка 52 - ВыборкаПартия.Партия.Дата – это тоже не явный запрос. Как в п.7

17.  Строка 61 Движения.ТоварыНаСкладах. – не установлен вид движения. Это явно рег. Остатков, так что там надо явно его установить. При проведении должно ругнуться

18.   Строка 39 ВыборкаНоменклатура.Количество – по одной номенклатуре может быть несколько партий, и ВыборкаНоменклаутра будет иметь итог больше чем запрошенное в документе количество. То же самое и с Суммой при формировании движений. И таже проблема с проверкой остатков ВыборкаНоменклатура.Количество > ВыборкаНоменклатура.КоличествоОстаток

19.   Ну еще момент в запросе, что нет группировки по номенклатуре и партии. Если в документе будет указаны одинаковые номенклатуры и партии в 2х строках, то будет не корректное списание партий, т.к. там же левое соединение по этим полям.