gifts2017

Программистские этюды

Опубликовал г. Казань Рустем Гумеров (Rustig) в раздел Программирование - Теория программирования

Рассматриваются задачи, связанные с учетом характеристик номенклатуры:
1) Обход итогов при партионном списании по ФИФО для пары Номенклатура+Характеристика
2) Обмен сведениями об остатках номенклатуры с помощью XML для пары Номенклатура+Характеристика
Дополнительно. Внимание новичкам – типовая консоль запросов.

Посвящается сайту "Математические этюды" http://www.etudes.ru/

Все рассмотренные примеры отлаживались на конфигурации "Управление торговлей 10.3". Задачи взяты из жизни, а решения не претендуют на уникальность или универсальность. Тем более что, пока я писал статью, на ум приходили совсем уже другие решения... Smile

 Этюд 1. Обход итогов при партионном списании по ФИФО для пары Номенклатура+Характеристика

Есть определенная схема построения запроса при программировании метода списания стоимости товара по ФИФО. Она представлена на рис. 1.

рис. 1.

Понятно, что схема учебная – в жизни учет товаров более сложен. Так, например, в конфигурации «Управление торговлей» учет товара дополнительно может вестись в разрезе характеристик. Что это значит применительно к нашей задаче? А то, что добавляется еще один разрез учета – характеристика, отдельно по которой нужно учитывать  сумму и количество партии.

Дополнительный разрез учета добавляет проблем при использовании  стандартной схемы построения запроса. Подробно об этих проблемах описано в статье http://infostart.ru/public/125988/ .

И замечу, что речь не идет о других способах конструирования запросов, как например:

http://infostart.ru/public/99207/

или

http://www.nashe1c.ru/materials-view.jsp?id=312

Так вот, что я сделал. Пару Номенклатура+Характеристика однозначно определяет поле Характеристика, потому что Номенклатура = Характеристика.Владелец. Такое соответствие относится только к товарам, а к таре не относится – тару однозначно определяет сама Номенклатура. Поэтому в запросе я дополнительно реализую Группировочное поле в результирующей таблице, по которому беру Итоги (рис. 2,3).

рис. 2.

рис. 3.

  Далее в цикле по ГруппировочномуПолю Товар и Характеристику определяю так:

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

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

   Если
ТипЗнч(Выборка.ГруппировочноеПоле) = Тип("СправочникСсылка.ХарактеристикиНоменклатуры") Тогда

   
Товар = Выборка.ГруппировочноеПоле.Владелец.Наименование;
   
Характеристика = Выборка.ГруппировочноеПоле.Наименование;
   
Код = Выборка.ГруппировочноеПоле.Владелец.Код;

  ИначеЕсли
ТипЗнч(Выборка.ГруппировочноеПоле) = Тип("СправочникСсылка.Номенклатура") Тогда

   
Товар = Выборка.ГруппировочноеПоле.Наименование;
   
Характеристика = "";
   
Код = Выборка.ГруппировочноеПоле.Код;

  Иначе
//на всякий случай

   
Товар = "Неизвестный товар";
   
Характеристика = "";
   
Код = ""
;

КонецЕсли;

Товар и Характеристику надо определять как минимум для вывода сообщения по товару (таре), по которой не хватает остатка:

 

Если НужноСписать>ОстатокНаСкладе Тогда

 
Сообщить("Подсистема учета ТЗР: на складе не хватает товара"
 
+ Символы.ПС + "По документу - " + СтрТЗ.Документ

  + Символы.ПС + "Склад - " + ТекСклад //СтрТЗ.Документ.Склад
 
+ Символы.ПС + "Товар - " + Товар + " (код " + Код + ")"
 
+ ?(НЕ ПустаяСтрока(Характеристика), Символы.ПС + "Характеристика - " + Характеристика, "")
  +
Символы.ПС + "Не хватает - " + (НужноСписать-ОстатокНаСкладе) + " кг. "
 
+ Символы.ПС + "Нужно списать - " + НужноСписать + " кг. "
 
+ Символы.ПС + "Тек. остаток - " + ОстатокНаСкладе + " кг.", СтатусСообщения.Внимание);

 
Отказ
= Истина;
  Продолжить;

КонецЕсли;

Далее все алгоритмы проходят по стандартной схеме списания по ФИФО. Как это реализовано в конфигурации УТ, я не анализировал. Подобную задачу решил для новой подсистемы учета транспортно-заготовительных расходов. Знаете, когда ТЗР распределяется по сумме товара? Вот это из этой оперы.

 *Идея использования рисунка схемы построения запроса взята из методических материалов курса обучения, который я проходил давным-давно. По части авторства: рисунок нарисован мною с нуля, схема сильно изменена по сравнению с источником.

 

 Этюд 2. Обмен сведениями об остатках номенклатуры с помощью XML для пары Номенклатура+Характеристика

Сперва постановка задачи, которую я давным-давно реализовывал… Привычная ситуация, когда при обращении клиента менеджер по продажам видит в информационной базе наличие товара по складам только своей компании, о наличии товара на складах поставщиков узнает по телефону. В ситуации, когда определенный вид товара поставляется только одной компанией-дистрибьютором, можно договориться с ней об электронном обмене информацией об остатках через интернет.

Я реализовал обмен информацией с помощью xml,  выгрузка и загрузка остатков происходила только для так называемых «свободных» остатков,  количество товара выгружалось (загружалось) с учетом характеристик товара; серии и качество товара учитывать не надо было.

В конфигурации УТ можно вести количественный учет товаров в разрезе дополнительных параметров, так называемых характеристик номенклатуры: цвет, размер и других потребительских свойств.

Для нас важно знать не только, сколько товара осталось в наличии на удаленном складе поставщика, но и какого, судя по потребительским характеристикам. Поэтому механизм выгрузки и загрузки данных должен учитывать характеристики товара. Учет по сериям (при выгрузке-загрузке) производить не нужно, так как эта информация не интересна нашему клиенту.

Вообще говоря, учет характеристик при выгрузке и загрузке файла обмена не считается тривиальной задачей, поскольку, если товар в разных информационных базах идентифицируется по совпадению артикула, то характеристики – только по одновременному совпадению названия свойства и значения показателя этого свойства. Например, если в одной базе характеристика «цвет обуви» задается как «Цвет», а в другой – «Цвет обуви», то для одного и того же 43 размера эти товары не будут идентифицированы как совпадающие. Потому что у них разные названия характеристики, которая определяет цвет обуви.

Таким образом, задача обрисовывается такая: при загрузке файла xml при совпадении названия характеристики и значения показателя характеристики с характеристикой товара текущей базы необходимо считать, что указанное количество свободного остатка относится к этой характеристике. Если хотя бы одна характеристика не совпадает, или нет одинаковых характеристик, то необходимо считать, что свободный остаток регистрируется по товару без характеристик. Считается, что для уточнения информации об остатках товаров без характеристик следует связываться с ответственным менеджером поставщика-дистрибьютора.

Теперь о реализации. Файл выгрузки представлен на рис. 4.

Рис. 4.

Видно, что при наличии остатка в разрезе характеристики – характеристика товара раскладывается на составляющие ее свойства и значения этих свойств. К примеру, для товара с артикулом «Б-130005» характеристика товара имеет свойства «Размер=36», «Полнота=5», «Тип4Кожи=Натуральная кожа».

Следует обратить внимание на название узла «Тип4Кожи». В программе «1С:Управление торговлей» свойство имеет название «Тип кожи», узнаваемое пользователем. XML-теги не определены жестко: разработчик вправе придумать свои собственные теги. Но по xml-стандарту название узлов в xml-файлах не должны содержать пробелов и других символов наподобие «!;%*()_+».

Поэтому для выгрузки свойств товара реализован механизм, который заменяет «некорректные» символы на цифры, а при загрузке остатков наоборот – цифры заменяет на символы. Кому интересно будет, отдельно выложу исходники для демонстрации идеи. Хотя считаю, что это слишком просто реализуется. Так как цифр имеется ограниченное количество (от 0 до 9), то такая замена может происходить только с ограниченным числом символов. Символы, не вошедшие в этот список, исключаются из названий свойств – при записи характеристики происходит проверка (рис. 5).

Рис. 5.

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

При загрузке xml-файл считывается, информация записывается во временную таблицу:

 


ОстаткиТЗ = Новый ТаблицаЗначений;
ОстаткиТЗ.Колонки.Добавить("Номенклатура", Новый ОписаниеТипов("СправочникСсылка.Номенклатура"));
ОстаткиТЗ.Колонки.Добавить("ХарактеристикаНоменклатуры", Новый ОписаниеТипов("СправочникСсылка.ХарактеристикиНоменклатуры"));
ОстаткиТЗ.Колонки.Добавить("Количество", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15,3)));

ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл(ФайлXML.ПолноеИмя);

ФормироватьСтруктуру = Ложь;
Пока
ЧтениеXML.Прочитать() Цикл

  Если
ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
     
ИмяУзла = ЧтениеXML.Имя;
      Если
ИмяУзла = "ЗаписьРегистра" Тогда
         
НоваяСтрокаТЗ = ОстаткиТЗ.Добавить();
      КонецЕсли;
      Если
ИмяУзла = "ХарактеристикаНоменклатуры" Тогда
         
ХарактеристикаНоменклатуры = Новый Структура;
         
ФормироватьСтруктуру
= Истина;
      КонецЕсли;
      Если
ИмяУзла = "Количество" Тогда
         
ФормироватьСтруктуру = Ложь;
         
НоваяСтрокаТЗ["ХарактеристикаНоменклатуры"] = ПолучитьЗначениеИзСтроки(ХарактеристикаНоменклатуры, "ХарактеристикаНоменклатуры");
      КонецЕсли;
  ИначеЕсли
ЧтениеXML.ТипУзла = ТипУзлаXML.Текст Тогда
      Если
ИмяУзла = "Номенклатура" или ИмяУзла = "Количество" Тогда
         
НоваяСтрокаТЗ[ИмяУзла] = ПолучитьЗначениеИзСтроки(ЧтениеXML.Значение, ИмяУзла);
      Иначе
          Если
ФормироватьСтруктуру Тогда
             
ХарактеристикаНоменклатуры.Вставить(ИмяУзла, ЧтениеXML.Значение
);
          КонецЕсли;
      КонецЕсли;
  КонецЕсли;

КонецЦикла;

ЧтениеXML.Закрыть
();

 

Дам пояснение. Для работы с XML-документами используется модель последовательного доступа, что означает следующее. При считывании структуры xml-файла:

1)      мы перебираем узлы сверху-вниз;

2)      мы не перескакиваем от узла к узлу, а целенаправленно анализируем: достигнуто «НачалоУзла» или «ТекстУзла»;

3)      когда проходим цикл по узлам, анализируем название узла.

Фактически запись и чтение данных из XML-документа производится «фрагментами» элементов. При этом очевидно, что при работе с XML-документами, имеющими сложную структуру, реализация процедур будет также сильно усложняться.

 

Предоставлю код, который позволяет из строкового значения xml-узла получить соответствующий в базе данных элемент:

 

Функция ПолучитьЗначениеИзСтроки(ЗначениеУзла, ИмяУзла)

 
Рез = Неопределено;

  Попытка
  Если
ИмяУзла = "Номенклатура" Тогда //найдем по артикулу

     
Запрос = Новый Запрос;
     
Запрос.Текст = "ВЫБРАТЬ
      | Номенклатура.Ссылка
      |ИЗ
      | Справочник.Номенклатура КАК Номенклатура
      |ГДЕ
      | Номенклатура.Артикул = &Артикул
      | И Номенклатура.ПометкаУдаления = ЛОЖЬ"
;

     
Запрос.УстановитьПараметр("Артикул", ЗначениеУзла);

     
Результат = Запрос.Выполнить();
      Если
Результат.Пустой() Тогда
         
ТекущаяНом = Справочники.Номенклатура.Новая;
          Возврат
Справочники.Номенклатура.Новая;
      КонецЕсли;

     
Выборка = Результат.Выбрать();

     
...

     
//выбираем только один элемент
     
Если Выборка.Следующий() Тогда
         
ТекущаяНом = Выборка.Ссылка;
          Возврат
Выборка.Ссылка;
      КонецЕсли;

  ИначеЕсли
ИмяУзла = "ХарактеристикаНоменклатуры" Тогда

      Если
ТекущаяНом = Справочники.Номенклатура.Новая Тогда
          Возврат Неопределено;
      КонецЕсли;

     
ЗапросПоХарактеристикам = Новый Запрос;
     
ЗапросПоХарактеристикам.Текст = "ВЫБРАТЬ
      | ЗначенияСвойствОбъектов.Объект,
      | ЗначенияСвойствОбъектов.Свойство,
      | ЗначенияСвойствОбъектов.Значение.Наименование КАК Значение
      |ИЗ
      | РегистрСведений.ЗначенияСвойствОбъектов КАК ЗначенияСвойствОбъектов
      |ГДЕ
      | ЗначенияСвойствОбъектов.Объект.ПометкаУдаления = ЛОЖЬ
      | И ЗначенияСвойствОбъектов.Объект.Владелец = &Владелец"
;

     
ЗапросПоХарактеристикам.УстановитьПараметр("Владелец", ТекущаяНом);

     
ТаблицаХарактеристик = ЗапросПоХарактеристикам.Выполнить().Выгрузить();
      Если
ТаблицаХарактеристик.Количество() = 0 Тогда
          Возврат Неопределено;
      КонецЕсли;

     
//ЗначениеУзла - для характеристики в данном случае это Структура,
      //Ключ - название свойства, например Цвет, Размер и т.д.
      //ЗначениеКлюча - значение свойства
     
СписокПодходящихХарактеристик = Новый Массив;
      Для Каждого
КлючИЗначение Из ЗначениеУзла Цикл
     
         
//здесь НазваниеСвойства подготавливается по значению КлючИЗначение.Ключ

          ...
         
НайденноеСвойство = ПланыВидовХарактеристик.СвойстваОбъектов.НайтиПоНаименованию(НазваниеСвойства, Истина);
         
//здесь же срабатывает проверка, если найденное свойство = пустой ссылке
         
Если НайденноеСвойство.НазначениеСвойства <> ПланыВидовХарактеристик. НазначенияСвойствКатегорийОбъектов.Справочник_ХарактеристикиНоменклатуры Тогда
               Продолжить;
          КонецЕсли;


         
ПараметрыОтбора = Новый Структура;
         
ПараметрыОтбора.Вставить("Свойство", НайденноеСвойство);
          ПараметрыОтбора.Вставить("Значение", КлючИЗначение.Значение);

         
МассивПодходящихСтрокХарактеристик = ТаблицаХарактеристик.НайтиСтроки(ПараметрыОтбора
);
          Если
МассивПодходящихСтрокХарактеристик.Количество() = 0 Тогда
               Возврат Неопределено;
          КонецЕсли;

          Для Каждого
Стр Из МассивПодходящихСтрокХарактеристик Цикл
               Если
СписокПодходящихХарактеристик.Найти(Стр.Объект) = Неопределено Тогда
                   
СписокПодходящихХарактеристик.Добавить(Стр.Объект);
               КонецЕсли;
          КонецЦикла;

         
//будем сокращать таблицу подходящих характеристик
         
ЗапросПоХарактеристикам.Текст = ЗапросПоХарактеристикам.Текст + "
          | И ЗначенияСвойствОбъектов.Объект В (&СписокХарактеристик)"
;
         
ЗапросПоХарактеристикам.УстановитьПараметр("СписокХарактеристик", СписокПодходящихХарактеристик);

         
ТаблицаХарактеристик = ЗапросПоХарактеристикам.Выполнить().Выгрузить
();

      КонецЦикла;

      Если
ТаблицаХарактеристик.Количество() = 0 Тогда
          Возврат Неопределено;
      КонецЕсли;

     
Рез = ТаблицаХарактеристик[0].Объект;

  ИначеЕсли
ИмяУзла = "Количество" Тогда
     
Рез = Число(ЗначениеУзла);
  КонецЕсли;

  Исключение

      ...

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


  Возврат
Рез;

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

Прокомментирую. Номенклатура (или товар в нашем случае) определяется по переданному артикулу. С этим сложностей нет. А вот как быть с характеристикой? Каждая характеристика в терминах конфигурации УТ представляет собой набор свойств со своими значениями. Хранятся такие наборы в регистре сведений. И как бы ну очень хочется использовать что-то наподобие метода ТаблицыЗначений НайтиСтроки(ПараметрыОтбора), в параметры отбора которого можно передать загружаемый набор свойств со своими значениями. На выходе хотим получить определенную характеристику товара. Но не тут-то было! В параметры отбора нельзя передать загружаемый набор свойств – можно только одно свойство и его значение через Структуру. Выход – использовать запрос к нашему регистру сведений. А суть предложенного алгоритма – при обходе xml-узлов наращивать набор свойств и значений, передавать набор в запрос, проверять наличие очередного свойства и значения в регистре и так по кругу по всем загружаемым свойствам.


 Этюд 3. Дополнительно. Внимание новичкам – типовая консоль запросов.

 

Вы когда-нибудь обращали внимание, иногда при выполнении запроса в консоли запросов появляется окно сообщения: «Ожидается выражение «Выбрать» ?.. И даже номер строки указан, в которой происходит ошибка.

Рис. 6.

Так вот, консоль запросов позволяет обрабатывать только часть выделенного текста в запросе. Я использую эту возможность при просмотре результата временных и вложенных таблиц или при редактировании только части запроса, входя в конструктор выделенного текста запроса. Для просмотра временных таблиц следует закомментировать выражение «Поместить», выделить часть текста запроса и нажать «Выполнить». После просмотра следует не забыть удалить комментарии в строке «Поместить» (рис. 7). Вообще-то, об этой возможности консоли запросов написано в справке, но кто ж ее читал именно для консоли запросов?

Рис. 7.

Картинка для анонса любезно предоставлена по лицензии GNU:

http://ru.wikipedia.org/wiki/Файл:Universal_joint_transparant.gif

Центр автоматизации, ИП Гумеров Р.И. http://готовые-решения-1с.рф/

См. также

Подписаться Добавить вознаграждение

Комментарии

0. г. Казань Рустем Гумеров (Rustig) 03.07.12 15:31
Рассматриваются задачи, связанные с учетом характеристик номенклатуры:
1) Обход итогов при партионном списании по ФИФО для пары Номенклатура+Характеристика
2) Обмен сведениями об остатках номенклатуры с помощью XML для пары Номенклатура+Характеристика
Дополнительно. Внимание новичкам – типовая консоль запросов.



Перейти к публикации

1. Aleksandr Filonov (AleksSF) 04.07.12 09:00
Почему-то рисунки не видны
CaSH_2004; Sherdrada; +2 Ответить 2
2. г. Казань Рустем Гумеров (Rustig) 04.07.12 10:28
3. Aleksandr Filonov (AleksSF) 04.07.12 10:37
4. Александр Рытов (Арчибальд) 04.07.12 10:55
(2) Rustig, положи картинки в раздел "Изображения" и ссылки перещелкни.
5. Stamper (Stamper) 04.07.12 11:12
вот черт побери, а я всё по инерции считал это "не найдено ВЫБРАТЬ" багом, а это фича =)))
спасибо
6. Модератор раздела Доржи Цыденов (support) 04.07.12 14:19
Картинка для анонса супер! Плюс )
7. г. Казань Рустем Гумеров (Rustig) 04.07.12 15:03
(3), (4) изображения выложил. в IE до сих пор не видно, в Мозиле - видно.
Арчи, про ссылки не понимаю как перебить - я картинки вставлял копи-пастом.
8. Kоstik Matiushkin (motkot) 04.07.12 19:34
Rustig, если критику воспринимаешь правильно, то такая конструкция "Выборка.ГруппировочноеПоле.Владелец.Наименование" приводит к дополнительному обращению к БД, следовательно, приводит к дополнительным накладным расходам. Решение: выбирать все необходимые поля сразу в запросе.
9. Алексей Константинов (alexk-is) 04.07.12 20:17
+(8) Ещё хотелось бы добавить, что работать с РегистрСведений.ЗначенияСвойствОбъектов нужно через ВЫРАЗИТЬ()
Например,
ВЫРАЗИТЬ(ЗначенияСвойствОбъектов.Объект КАК ...).Владелец = &Владелец
10. Kоstik Matiushkin (motkot) 04.07.12 20:46
(9) alexk-is, читал бегло, сразу бросилось в глаза первое...
11. г. Казань Рустем Гумеров (Rustig) 04.07.12 21:41
(9) не убедительно, :). Конструкция Выразить() предназначена для других ситуаций.
Хотя я не эксперт по технологическим вопросам... :)
12. г. Казань Рустем Гумеров (Rustig) 04.07.12 21:43
(8) критике рад! о чем вы пишите знаю, но никогда не применяю, потому что несущественно - документ проводится, глазом не успеете моргнуть :)
13. Алексей Константинов (alexk-is) 05.07.12 07:30
(11) Для каких таких других?

В данном случае я пытаюсь тонко намекнуть, что следует избегать скрытых множественных соединенй в запросах. Например, при попытке выполнить запрос ЗапросПоХарактеристикам в УПП под MS SQL я получаю:
Построенный запрос к СУБД использует слишком много таблиц. Допустимо не более 256.

Посмотрите внимательно на тип данных измерения Объект: "ДокументСсылка, СправочникСсылка". Соответственно в запросе соединяются все таблицы по документам, справочникам и ещё, конечно, регистр сведений. Измерение Значение тоже составного типа, но там соединяется значительно меньше таблиц - около 15 справочников.

Такой запрос уже работает.
ВЫБРАТЬ
	ЗначенияСвойствОбъектов.Объект,
	ЗначенияСвойствОбъектов.Свойство,
	ЗначенияСвойствОбъектов.Значение.Наименование КАК Значение
ИЗ
	РегистрСведений.ЗначенияСвойствОбъектов КАК ЗначенияСвойствОбъектов
ГДЕ
	ВЫРАЗИТЬ(ЗначенияСвойствОбъектов.Объект КАК Справочник.ХарактеристикиНоменклатуры).ПометкаУдаления = ЛОЖЬ
	И ВЫРАЗИТЬ(ЗначенияСвойствОбъектов.Объект КАК Справочник.ХарактеристикиНоменклатуры).Владелец = &Владелец
...Показать Скрыть
Было бы неплохо разобраться и с ЗначенияСвойствОбъектов.Значение.Наименование

ВЫРАЗИТЬ(ЗначенияСвойствОбъектов.Значение КАК ...).Наименование
14. г. Казань Рустем Гумеров (Rustig) 05.07.12 08:57
(13) спасибо! на будущее учту. вы все правильно написали. Я-то имел в виду, что конструкцию приведения типов Выразить() надо использовать только по необходимости, а в моем случае ее не было, судя по работоспособности алгоритма. Хотя теперь, если судить по тому, как устроен механизм запросов, я бы включил выражение Выразить() в запрос. Так что еще раз вам спасибо. Добавлю, что на момент отладки в регистре было мало данных, возможно поэтому ошибок не возникало.

а вас не смущает, что во второй задаче запрос доформировывается и вызывается каждый раз при обходе цикла?
15. Kоstik Matiushkin (motkot) 05.07.12 10:46
(12) Rustig, производительность системы не измеряется в "морганиях глазами". Попробуйте для начала использовать "замер производительности" до и после изменений в коде. Ответ получите объективно в цифрах.
16. Алексей Константинов (alexk-is) 05.07.12 11:30
(14)
а вас не смущает, что во второй задаче запрос доформировывается и вызывается каждый раз при обходе цикла?
Смысл этого действия не совсем понятен. Точнее так. В механизме реализации есть несколько недочетов. Например, если в ЗначениеУзла будет несколько КлючИЗначение, то текст запроса будет
ВЫБРАТЬ
    ЗначенияСвойствОбъектов.Объект,
    ЗначенияСвойствОбъектов.Свойство,
    ЗначенияСвойствОбъектов.Значение.Наименование КАК Значение
ИЗ
    РегистрСведений.ЗначенияСвойствОбъектов КАК ЗначенияСвойствОбъектов
ГДЕ
    ЗначенияСвойствОбъектов.Объект.ПометкаУдаления = ЛОЖЬ
    И ЗначенияСвойствОбъектов.Объект.Владелец = &Владелец
    И ЗначенияСвойствОбъектов.Объект В (&СписокХарактеристик)
    И ЗначенияСвойствОбъектов.Объект В (&СписокХарактеристик)
    И ЗначенияСвойствОбъектов.Объект В (&СписокХарактеристик)
    И ...
...Показать Скрыть


Кроме этого
Почему бы не передавать в запрос "загружаемый набор свойств" в виде ТаблицыЗначений и получить список подходящих характеристик?
У меня нет возможности проверить, но как мне кажется, вот такой запрос должен работать
ВЫБРАТЬ
	ТаблицаЗначений.Свойство КАК Свойство,
	ТаблицаЗначений.Значение КАК Значение
ПОМЕСТИТЬ ТаблицаЗначений
ИЗ
	&ТаблицаЗначений КАК ТаблицаЗначений
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ РАЗРЕШЕННЫЕ
	ЗначенияСвойствОбъектов.Объект КАК Объект,
	ЗначенияСвойствОбъектов.Свойство КАК Свойство,
	ЗначенияСвойствОбъектов.Значение.Наименование КАК Значение
ПОМЕСТИТЬ СвойстваХарактеристик
ИЗ
	РегистрСведений.ЗначенияСвойствОбъектов КАК ЗначенияСвойствОбъектов
ГДЕ
	ЗначенияСвойствОбъектов.Объект ССЫЛКА Справочник.ХарактеристикиНоменклатуры
	И ВЫРАЗИТЬ(ЗначенияСвойствОбъектов.Объект КАК Справочник.ХарактеристикиНоменклатуры).Владелец = &Владелец
	И ВЫРАЗИТЬ(ЗначенияСвойствОбъектов.Объект КАК Справочник.ХарактеристикиНоменклатуры).ПометкаУдаления = ЛОЖЬ
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	СвойстваХарактеристик.Объект КАК Объект
ИЗ
	ТаблицаЗначений КАК ТаблицаЗначений
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ СвойстваХарактеристик КАК СвойстваХарактеристик
		ПО ТаблицаЗначений.Свойство = СвойстваХарактеристик.Свойство
			И ТаблицаЗначений.Значение = СвойстваХарактеристик.Значение

СГРУППИРОВАТЬ ПО
	СвойстваХарактеристик.Объект

ИМЕЮЩИЕ
	СУММА(1) = &КоличествоСвойств
...Показать Скрыть


Если что-то в запросе непонятно, спрашивайте...
17. г. Казань Рустем Гумеров (Rustig) 05.07.12 11:58
(15) все правильно вы пишите. иногда проверяю с помощью замера производительности. но как-то интуитивно: где-то считаю надо замерить, а где-то не замечаю разницы... оба ваши совета абсолютно верны и объективны. но не все программисты способны уделять время таким деталям. я не идеален :)
18. г. Казань Рустем Гумеров (Rustig) 05.07.12 12:01
(16) отлично что вы увидели этот момент. пусть каждый желающий выскажется. Я для себя, найдя другое решение, решил ничего не изменять. Алгоритмов достижения результата может быть несколько.
19. Осипов Сергей (fixin) 05.07.12 17:59
не знаю, пейсали автору или нет.

Когда делается списание с учетом характеристик, нужно делать обязательно отбор партий по серийным номерам документа.
Порой у товара может быть 10 000 серийников и отбор по хар-ке существенно ускоряет проведение.



Пусть использует, если нужно.
Текст запроса не вижу, потому не знаю...
20. г. Казань Рустем Гумеров (Rustig) 05.07.12 19:22
(19) опишите пожалуйста подробнее, :). Учет серий в рассмотренной подсистеме не предусмотрен, хотя в УТ отдельно ведется. заранее спасибо!
21. Владимир Самойлов (samamoiloff) 05.07.12 21:17
(6) А почему картинка - супер? Не понял. Интересно. Намекните хоть...
22. Павел Кучеренко (NCCSOFT) 05.07.12 21:31
К сожалению, не понял практическую полезность статьи (разве что для обучения). "Обход итогов списаний по ФИФО", и "сам алгоритм списания по ФИФО" разные вещи. И 1С 77...82 не способен быстро рассчитывать себестоимость (проверено на практике... тут всё подробно расписал: NCC:Бизнес-Аналитика (расчет себестоимости за 2 секунды +OLAP-инструмент)). И вообще SQL устарелая технология, я отказался от неё уже 3 года - только NO-SQL.
Мне понравилась статья на хабре: Производительность C++ vs. Java vs. PHP vs. Python. Тест «в лоб».
r := 0; for i := 0 to 9999 do for j := 0 to 9999 do r := ( r + ( i * j ) mod 100) mod 47;

Я не поленился, и сделал тесты еще на нескольких языках (включая 1С), и вот что вышло, результат теста (должно получиться r = 39):
Delphi 7, XE, XE2 - 4.7 секунды
C++, JAVA 7 Server - 4.7 секунды
PERL 5 - 72 секунды
PHP 5 - 58 секунд
1С 77 - 2230 секунд (ОФИГЕТЬ!!!)
1С 82 - 496 секунд (НО ТОЖЕ ОФИГЕТЬ!!)

FastScript 4 (от FastReport.ru) - 114 секунд
Flash AS 2.0 - 700 секунд


Всё тестировал на старом своем компьютере (Атлон 3200Гц / 3Гб ОЗУ)
Хотел даже написать статью на инфостарте, но руки не долши.
Делайте выводы :-)
madonov; DoctorRoza; sashocq; Rustig; CaSH_2004; +5 Ответить 3
23. г. Казань Рустем Гумеров (Rustig) 06.07.12 13:19
(22) спасибо за комментарий!
ваш комментарий очень полезен с практической точки зрения в плане обучения.
:) и у вас отличная программа (посмотрел видеоролик)! буду ее рекомендовать клиентам! это серьезно

а так еще немного "философии" добавлю, но это не только к вам относится :)
Из интервью http://www.livejournal.ru/themes/id/54277 : "Мой хороший знакомый, философ Александр Неклесса, дал определение, что образование - это встреча с ИНЫМ. Есть «я», и все что я знаю, представляю, умею. Когда я сталкиваюсь с чем-то непохожим на мои представления, у меня есть несколько разных способов столкновения. Я могу это уничтожить, проигнорировать или с этим встретиться. Если я встречаюсь, с тем, что не есть «я», а с иным, в этот момент и начинается настоящее образование."

Вы правильно заметили, "практическая полезность статьи" заключена "разве что для обучения". А для меня это еще и творческое самовыражение.
24. г. Казань Рустем Гумеров (Rustig) 06.07.12 18:44
Интересная и поучительная дискуссия развелась после комментария (22) на странице публикации Бизнес-Аналитики http://infostart.ru/public/70525/

Сохраню ее для истории.

Rustig 06.07.12 13:42
(0) хочется узнать, за счет чего перепроведение документов происходит быстрее?
я так это вижу:
1) у вас совершенно другая структура таблиц в базе,
2) у вас нет разного рода таблиц для хранения вспомогательной или другой справочной информации, используемой в документах,
3) и у вас в олап-кубе при проведении документа не проверяются разные флаги учетной политики, не производится расчет ПБУ 18, расчет НДС, не затрагиваются дополнительные регистры сведений (как при проведении документов, связанных с ОС, например).

Верно?

У вас сразу фиксируется количественный и суммовой приход-расход в разрезе документа-регистратора, номенклатуры, характеристики, серий и м.б. еще чего?
М.б. у вас в базе нет разделения таблиц на документы и регистры накопления.
Все хранится в одной таблице, и документом и одновременно регистром накопления по факту является запись этой таблицы. Правильно?
Если я ошибаюсь, раскройте пожалуйста секрет.

При всем при этом я нисколько не уменьшаю ценность вашей программы. Она для меня очевидна.
Заранее спасибо за ответ.
С уважением, Рустем Гумеров

42.
NCCSOFT 06.07.12 14:48

(41) Чтобы прийти к этому решению, пришлось отказаться от трех вещей (технологий, постулатов), и сделать "всё с нуля". Последняя 4-я вещь от которой нужно отказаться - это тормозной компонент OLAP-навигатор (который теперь единственное узкое место, поскольку его задача - тупо как "OLAP-Viewer", а он тормозит... из-за опять таки, старых технологий TDataSet, на основе которых он сделан).
1) Отказался от SQL
2) Отказался от регистров (сам документ и есть как регистр)
3) Загнал всю базу в ОЗУ (технология "in memory") и сделал расчет себестоимости с учетом доп.расходов.
Секрет написан мелким розовым шрифтом в разделе "Разработчикам" :-) Я пробовал сделать расчет себестоимости на языке SQL, для 100 движений работает, а для 1 миллиона нет.
У меня "проведение документов", наверное, не совсем корректно сказано - точнее сказать "расчет себестоимости с учетом дополнительных транспортных расходов", т.к. это ГЛАВНАЯ ЦЕЛЬ этой программы, и слабое место у 1С. Мои заказчики используют эту программу для принятия управленческих решений. Выручка, себестоимость, прибыль - могут рассчитаны у учетом НДС или без НДС.

Да, всё верно вы написали (41), документов ОС (учета основных средств) там вообще нет. А все остальные документы, типа ПКО, РКО и подобные простые, они двигают "+" или "-" различные оборотные показатели, которые OLAP сам подсчитает и покажет.
В расчете, помимо "расчета себестоимости", еще рассчитываются все остатки: товаров, денег, долгов, заявок, заказов.
И все эти показатели - отдельные колонки одной огромной таблицы, которая хранится в "ResDB.ncc" (первая таблица), а все длинные и повторяющиеся строки вынесены в словарик "ResDI.ncc" (вторая таблица). В итоге эти две таблицы занимают 285Мб, при общем базы DBF-файлов 1С в 7Гб.

43.
Rustig 06.07.12 15:59

я кстати, почему сразу спросил (41) - потому что сам об этом задумывался.
и еще, получается чтобы рассчитать себестоимость в 1С требуются следующие телодвижения:
1. Заполнить документ(-ы) в 1С --> 2. Провести документ(-ы) в 1С --> 3. Рассчитать себестоимость по закрытию месяца

С использованием вашей программы:
1. Заполнить документ(-ы) в 1С --> 2. Провести документ(-ы) в 1С --> 3. Выгрузить из 1С и загрузить в Олап-куб --> 4. Рассчитать себестоимость в Олап-кубе

То есть момент проведения документов в 1С (пункт 2) - никак не избежать.
И всякий раз, чтобы использовать вашу программу, надо загружать актуальные данные из 1С. Все верно?

44.
NCCSOFT 06.07.12 16:17

(43) У всех заказчиков ночью запускается обработка выгрузки всех документов в "NCC:Бизнес-Аналитику", и менеджеры работают с актуальными данными (без учета текущего дня). Если необходимы данные "на данную минуту", то они могу выгрузить данные в ручном режиме.

Поскольку, экспорт документов идет только если они проведены, то да, пункт 2 "проведение документа" необходим. Но программа "NCC:Бизнес-Аналитика" не нуждается в движениях регистров или бух-проводок, и она их не выгружает, т.к. при запуске "NCC:Бизнес-Аналитика" будет произведен расчет.

Экспорт данных из 1С сделан для 1С 77 "Торговля и Склад" или "Комплексная конфигурация". В принципе, если у кого есть желание, можно написать экспорт данных из 1С 82 или других любых программ учета.
25. fhn iyg (zigomodo) 10.07.12 16:17
Спасибо за статью,все разложено как по полочкам. Спасибо автору за то,что не поленился написать много букв)
26. Stamper (Stamper) 10.07.12 17:42
(22) NCCSOFT, любопытно про NO-SQL
известны ли примеры бизнес-программ на таких СУБД? если можно, ссылки дайте плз
27. Павел Кучеренко (NCCSOFT) 12.07.12 14:39
(26) NO-SQL означает "Not Only SQL" (т.е. не только SQL, в SQL тоже есть плюсы и полность отказываться было бы глупо).
Почитайте на хабре. Я сейчас делаю программу "NCC:Предприятие" ("убица 1С 8.3") (почти шутка) на этих принципах :-) только не смейтесь, это реально так. Она по функционалу как "1С Торговля и склад + финансы + логистика + закупки + заказы + упр.зарплата и персонал + производство + выгрузка в 1С 8.2 Бухгалтерию + CRM + CMS".

Это и моё творчество, и работа.

Примеры ссылок именно "бизнес-программ" не могу дать, т.к. не видел. Оно и понятно - это "на острие атаки", а всякие "соц.сети" не в счет.
28. Stamper (Stamper) 12.07.12 20:53
(27) NCCSOFT, я в курсе! по-этому и написал NO-SQL а не No-SQL ;) ну Вы поняли
если есть что показать -- вышлите на stamper собака ukr точка net, пожалуйста
а если еще нет, то не забудьте вписать мою почту в лист рассылки :)
29. Павел Кучеренко (NCCSOFT) 12.07.12 21:17
(28) Круто, реально круто! Впишу, обязательно впишу, как будут новости - вы первый в списке! Даже мои друзья (мы празновали мое 36-ти летие, отдыхали на Обском Море), они не в первых списках. Они сказали, что если бы узнали чем я занимаюсь (в советское время) - они вынуждены были сообщить об это в соответствующие органы... ИИ рулит...
30. nataon (nataon) 13.07.12 09:09
31. Алексей Опарихин (Al-X) 20.06.13 14:30
Спасибо Автору !! На некоторые вещи "прям глаза открылись"...
32. Александр Федоров (Sasha255n) 16.09.13 17:22
(25) zigomodo, Это иррония или скарказм, или вы взаправду все))))?
33. Александр Федоров (Sasha255n) 16.09.13 17:23
(31) Al-X, Открыл глаза .... Да.... Это иррония или скарказм, или вы взаправду все )))) ?
34. Сергей Зенюков (Sanario) 15.09.16 09:27
Эх. Спасибо за статью. Одно пожелание - скриншоты бы покрупнее - невидно нифига ничего.
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа