• Познакомьтесь с пентестом веб-приложений на практике в нашем новом бесплатном курсе

    «Анализ защищенности веб-приложений»

    🔥 Записаться бесплатно!

  • CTF с учебными материалами Codeby Games

    Обучение кибербезопасности в игровой форме. Более 200 заданий по Active Directory, OSINT, PWN, Веб, Стеганографии, Реверс-инжинирингу, Форензике и Криптографии. Школа CTF с бесплатными курсами по всем категориям.

7.7 Количество Измерений В Регистре

  • Автор темы olga13
  • Дата начала
Д

Дайнеко

Зачем тогда это измерение вообще нужно?
... Как по мне то СтрокуПартии ф топку

Мои пять копеек: самая умная мысль. Все туда.
Потом грамотно продумать структуру базы, а не лепить горбатого на ходу.
 
O

olga13

Я лично на 99.99 уверен, что она не в глПолучитьАтрибутыПартии

Вот процедура на которой все виснет:

Код:
Процедура Страна()
ВыбратьСтроки();
Пока ПолучитьСтроку() = 1 Цикл

глПолучитьАтрибутыПартии(Товар, Партия, СтрПартии, "ОстаткиТоваровОтгруженных");

Попытка
Страна = глСписок.ПолучитьЗначение(4);
Исключение
Сообщить("Не удалось получить атрибуты для партии " + Партия);
КонецПопытки;

КонецЦикла;
КонецПроцедуры

Где, по-вашему, ошибка?

Причем обрабатывается 1495 строк, а потом "Недостаточно памяти".
 
H

Hryv

А долго тест выполняется?

Если не очень долго, то сначала попробуйте так

Попытка
Страна = глСписок.ПолучитьЗначение(4);
глСписок = "";
Исключение
Сообщить("Не удалось получить атрибуты для партии " + Партия);
КонецПопытки;

а я пока еще подумаю

практически 100%, что 1С не удаляет из памяти эти глСписок-и
по крайней мере до завершения цикла

можно еще так попробовать
Код:
Процедура Страна()
Список = СоздатьОбъект("СписокЗначений");
ВыбратьСтроки();
Пока ПолучитьСтроку() = 1 Цикл

глПолучитьАтрибутыПартии(Список, Товар, Партия, СтрПартии, "ОстаткиТоваровОтгруженных");

Попытка
Страна = Список.ПолучитьЗначение(4);
Список.УдалитьВсе();
Исключение
Сообщить("Не удалось получить атрибуты для партии " + Партия);
КонецПопытки;

КонецЦикла;
КонецПроцедуры


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

Возврат глСписок;

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

но лучше если бы помогло глСписок = "";
если вы глПолучитьАтрибутыПартии уже используете в разных местах, то не надо будет исправлять
 
O

olga13

Мои пять копеек: самая умная мысль. Все туда.
Потом грамотно продумать структуру базы, а не лепить горбатого на ходу.

Ваши предложения?

Вот кусок реальной накладной. Одни и тот же товар, разные производители, разные страны, разный процент комиссионного вознаграждения.

Добавлено:
Если не очень долго, то сначала попробуйте так

Попробовала, результат тот же.
 

Вложения

  • Договор1269.rar
    14,9 КБ · Просмотры: 142
Д

Дайнеко

Ваши предложения?

Ну мыслимо ли дело? Что бы выяснить страну, перебирать кучу строк чего-то там. Да если бы даже Оно и не висло, то все равно бы никуда не годилось.
Одним из способов решения проблемы, есть устранение самой проблемы. Чем ломать голову над вопросом "как достать" надо долго и внимательно обдумать структуру базы. Вот изложите коротенько ее структуру.
P.S.
Чур, не выкладывать MD и полное описание конфигурации!
 
H

Hryv

Конечно, чем лучше спроектирована структура регистров, тем удобнее потом программировать
Но лично мне сейчас стало интересно выяснить и устранить причину этой странной ошибки


Я правильно понимаю, что в стороке
Страна = Список.ПолучитьЗначение(4);

Страна - это реквизит ТЧ того дока внутри которого находится Страна()?
 
H

Hryv

Ну самым простым, для начала, будет отказ от глобальной функции, хотя бы узнаем она ли память жрет
Список был раньше устранен, а РегБН = СоздатьОбъект - остался

Код:
Процедура Страна()
Список = СоздатьОбъект("СписокЗначений");
РегБН = СоздатьОбъект("Регистр.ОстаткиТоваровОтгруженных");

ВыбратьСтроки();
Пока ПолучитьСтроку() = 1 Цикл
РегБН.УстановитьФильтр(,,,Товар,Партия,СтрПартии);
РегБН.ВыбратьДвижения(Партия.ДатаДок, Партия.ДатаДок);
Пока РегБН.ПолучитьДвижение() = 1 Цикл
Если Партия.ПолучитьСтрокуПоНомеру(РегБН.НомерСтроки()) = 1 Тогда
Страна = Партия.Страна;
Прервать; //хотя если все как надо, то и так всегда только один проход будет
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецПроцедуры
 
H

Hryv

Ольга13, вдруг не заметили, я в последнем посте на 1-ой странице вариант предложил
 
O

olga13

Ну самым простым, для начала, будет отказ от глобальной функции, хотя бы узнаем она ли память жрет
Список был раньше устранен, а РегБН = СоздатьОбъект - остался

Попробовала, обработалось на 1 строку больше :)
Добавила еще в цикл Список.УдалитьВсе() - результат тот же.
Судя по замеру производительности, больше всего времени жрет Партия.ПолучитьСтрокуПоНомеру(РегБН.НомерСтроки()) - 89.7%. Может, и память в ту же пропасть уходит?

Добавлено:
Ольга13, вдруг не заметили, я в последнем посте на 1-ой странице вариант предложил

Спасибо, я видела и пробовала - все равно вылетает.
 
H

Hryv

Блин, странно
А что у вас с релизом самой платформы?

Я еще попробовал бы напрямую перебор строк Партии
Думаю, что не на много дольше по времени будет, чем с использованием регистра (хотя, конечно, точно не узнаем пока не проверим)

Если заработает в принципе, то можно будет думать как оптимизировать

ЗЫ в последенем примере строку Список = СоздатьОбъект("СписокЗначений"); я просто забыл удалить
 
P

puh14

Если я правильнопонял - то партия - это документ оприходования. Жаль. немного расскажу как у меня устроено.

Предметная область - оптовая торговля медикаментами. Целая туча ограничений и отчетов. Во всех документах, двигающих товар есть измерение серия номенклатуры. Это элемент справочника серии подчиненный справочнику номенклатура. В этой серии хранится практически всё по медикаменту - сертификаты, сроки годности, цены реестра, цены поставщиков, поставщик, ГТД, страна проихождения и.т.д. При этом во всех регистрах, в которых есть измерение номенклатура также есть и измерение серия номенклатуры. То бишь при создании любого отчета на этих регистрах я всегда могу поставить любое из полей серии в условие/группировку. Одна из тонкостей - каждая строка документов поступления содержит уникальную ссылку на серию, даже если введены копированием и товары ничем не отличаются - надо для разделения себестоимости по строкам, цены прихода бывают разные.

Вот сколько за это время не требовали отчетов в разных комбинациях полей - никогда проблем не было. Если были тормоза - переписывал на прямой запрос.
 
O

olga13

Если заработает в принципе, то можно будет думать как оптимизировать

Мне все-таки больше понравилась идея puh14 со справочниками. И вовсе не много там возни, я уже попробовала. Зато какое повышение быстродействия!
Хотя все равно интересно, где ошибка. Эта же функция стоит в этом же документе в процедуре Заполнить() в теле цикла по группировкам запроса - и все работает -_-
 
Д

Дайнеко

Даже не представляю, как это можно сделать коротенько.

Вот так:
* Спр-к Товары

* Спр-к Партии - подчинен Товарам
- Ссылка на Приходную
- Страна ввоза (строка или ссылка на Спр-к)
- Серия медикаментов
- Срок годности
- ......

* Регистр ОстаткиТоваров
Изм
- Склад
- Товар
- Партия
Рес
- Количество
- Стоимость

* Приходная
Шака
- Клиент
- Склад
ТЧ
- Товар
- Партия
- Количество
- Стоимость

А то уж народ устал спрашивать "Партия" - это что?

Ремарки:
* Puh14. Как видишь мое видение примерно такое-же. Только я вынужден не циклиться на фармацевтах, и называю не Серия а
Партия.
* Многие программы используют принцип: все данные набирается в колонках документа, а при записи нужное переписывается в спр-ки. И выше тут предлагалось так делать со Страной. Но я считаю это не технологичным.
Во-первых: когда в справочниках много заполняемых данных, то столько колонок в Приходной не нарисуешь. Кроме Страны и приведенных мной полей в Партии чего только может не быть: цвет, размер одежды, инд. номер партии завода, кол-во в упаковке (меняется у разных приходов) и т.д. до бесконечности.
Во-вторых: Пользователю так нравится, только пока он не освоился в программе. Потом его станет напрягать 15 колонок (по опыту, документ набирается 1 раз а просматривается раз 5-8).
В-третьих: А еще дублированность данных никогда к добру не приходит. Это нехорошо, когда пользователь заполняет в одном месте, а программа пользуется некоторой копией данных. Пусть чел знает, где что лежит. А программист не ломает голову откуда брать.
В-четвертых: о размере базы полезно заботится.
 
H

Hryv

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

И уже так и так получается, что причина ошибки не выясняется, а лишь обходится
 
O

olga13

Спасибо за дельные советы, обязательно воспользуюсь.
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!