Здравствуйте.
Мне директора дали задание что бы залоговые билеты приходовать и они при проведении списывались.
1. Завел я регистр накопления остатки "ЗалоговыеБилетыОбороты"
2. Создал документ "ОприходываниеЗБ" который формирует залоговые билеты в Регистр Накопления "ЗалоговыеБилетыОбороты".
и в модуле объекта документа "ЗалоговыйБилет" в процедуре "ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)" прописал:
Теперь выресовывается проблема: при отмене проведения, при записи, при проведении, зависает сильно, отдупляется через 40 секунд.
При отладке виснет на строке Результат = Запрос.Выполнить();.
Как можно решить данную проблему?
(1) BARDER, а что, остаток всегда берется самый последний какой есть ?
А если документ задним числом будут проводить, тогда не возникнет неправильных данных ?
по поводу оптимизации,
у вас сначала выгребается весь регистр, а потом обходится его результат - и условием ГДЕ, отбираются нужные записи.
Потому и долго, и будет еще дольше по мере увеличения записей в регистре.
А надо, сразу на виртуальную таблицу накладывать максимальное количество условий, чтобы потом обрабатывать минимальное количество строк.
в консоли запросов, в среднем окне куда перетаскиваете нужную таблицу объекта метаданных, кликнув мышкой на ней, и зайдя в свойства
там и указывай, параметры серии и номера.
(7) Boneman, в регистре накопления уникальные Серия + номер, и условия должны обрабатывать только одну строку или вообще не найдено.
Я не могу понять как он может обходить всю таблицу, если условия уже наложены.
(1) BARDER, вот совсем не понимаю, зачем вообще запрос? И точно это в ПередЗаписью?
Просто в процедуре обработки проведения делаете движение и все.
Один залоговых билет - один документ. Нечего придумывать лишнего.
(13) spacecraft, я уже вынес запрос в ОбработкуПроведения,
а как еще без запроса то?
В процедуре ПредЗаписью у меня еще есть запрос, который так же весит, там я выбираю первую запись для присвоения номера докменту:
Если ЭтотОбъект.Номер = "" Тогда
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| ЗалоговыеБилетыОборотыОстатки.СерияЗалоговогоБилета,
| ЗалоговыеБилетыОборотыОстатки.НомерЗалоговогоБилета КАК НомерЗалоговогоБилета,
| ЗалоговыеБилетыОборотыОстатки.Подразделение,
| ЗалоговыеБилетыОборотыОстатки.Организация,
| ЗалоговыеБилетыОборотыОстатки.КоличествоОстаток
|ИЗ
| РегистрНакопления.ЗалоговыеБилетыОбороты.Остатки КАК ЗалоговыеБилетыОборотыОстатки
|ГДЕ
| ЗалоговыеБилетыОборотыОстатки.КоличествоОстаток > 0
|
|УПОРЯДОЧИТЬ ПО
| НомерЗалоговогоБилета";
Результат = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = Результат.Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
ЭтотОбъект.Номер = ВыборкаДетальныеЗаписи.НомерЗалоговогоБилета;
ЭтотОбъект.Серия = ВыборкаДетальныеЗаписи.СерияЗалоговогоБилета;
КонецЦикла;
КонецЕсли;
(14) BARDER, во-первых, я говорил про запрос в (1). От него совсем нет толку.
во-вторых, странная у вас бизнес-логика приложения. Т.е. не пользователь выбирает бланк строгой отчетности "Залоговый билет" и с ним работает, а программа псевдослучайно выбирает билет и его проводит? А печатаете как? Бланки строгой отчетности должны быть напечатаны типографским способом. Печатать бланк на компьютере не разрешается. Единственно, это заполнять бланк на компьютере можно и печатать информацию о залоге на типографском бланке. В данном случае я не вижу правильного сопоставление номеров бланка и документа.
(15) spacecraft, Мне говорят, я делаю, остальным занимаются юристы. Раньше Мы на пустых типографических бланках печатали, но я так понял что этот вопрос решился, т.к. с бланком который сейчас печатает программа, с ним ездили куда то утверждать.
3. С другой стороны, если в п.2. выбирается всегда один билет, то смысла в цикле нет.
4. Ну и параметры действительно лучше в "Остатки(&Дата, Серия = &Серия И Номер = &Номер)"
5. Отсюда как бы плавно вытекает вопрос о том, в каком именно месте тормоза? Ведь алгоритм-то простой: получить остаток. Если он есть - списать, если его нет - отказ.
(16) starik-2005, Я сделал так, Спасибо, запрос начал выполняться за 2 секунды.
Теперь другой вопрос как оптимизировать запрос который выбирает первые, там запрос до 17 секунд и выше на SSD диске.
ВЫБРАТЬ ПЕРВЫЕ 1
ЗалоговыеБилетыОборотыОстатки.СерияЗалоговогоБилета,
ЗалоговыеБилетыОборотыОстатки.НомерЗалоговогоБилета КАК НомерЗалоговогоБилета,
ЗалоговыеБилетыОборотыОстатки.Подразделение,
ЗалоговыеБилетыОборотыОстатки.Организация,
ЗалоговыеБилетыОборотыОстатки.КоличествоОстаток
ИЗ
РегистрНакопления.ЗалоговыеБилетыОбороты.Остатки КАК ЗалоговыеБилетыОборотыОстатки
ГДЕ
ЗалоговыеБилетыОборотыОстатки.КоличествоОстаток > 0
УПОРЯДОЧИТЬ ПО
НомерЗалоговогоБилета
(23) Xershi, если бы я нашел ответ в курсах, тогда бы я не писал в тему сюда, я все курсы его по запросам пересмотрел, если конечно что не пропустил..
Я просто прошу помочь с проблемой
(27) Xershi, спасибо, я уже пробовал, он выбирает номер не тот что нужно, а если делаю сортировку по номеру, то подвисает, пока сформирует вт, потом то что сортируется, это как двойной запрос получается, и там ОЗУ нужно.... А у нас гиговые планки на компах
У меня номера строковые а в строковых 10 меньше чем 9))
Приблизительно так
Выбрать Первые 1 Минимум(Выбор когда Подстрока(Номер,2,1) = "" Тогда
1
когда Подстрока(Номер,3,1) = "" Тогда
2
когда Подстрока(Номер,4,1) = "" Тогда
3
когда Подстрока(Номер,5,1) = "" Тогда
4
когда Подстрока(Номер,6,1) = "" Тогда
5
//итд до максимальной длины номер
Конец) как ДлинаСтроки,
Номер из вт
сгруппировать по номер
упорядочить по ДлинаСтроки,Номер
А что, база файловая? Если так, то ускорить будет непросто.
1. Может быть один номер и серия для разных подразделений и организаций? Если нет, то засунуть их в ресурсы.
2. Номер и серия всегда являются числом (или номер, или серия)? Если да - сделать параметр числовым.
3. Индексировать номер и серию.
4. Пересчитать итоги регистра.
А что, база файловая? Если так, то ускорить будет непросто.
1. Может быть один номер и серия для разных подразделений и организаций? Если нет, то засунуть их в ресурсы.
2. Номер и серия всегда являются числом (или номер, или серия)? Если да - сделать параметр числовым.
3. Индексировать номер и серию.
База файловая,
1. в ресурсы не могу, так как ресурсы числовые, а мне строковые нужны( серия состоит из букв такие как ТП, ТЦ, СТ, КС, а номер должен быть из шести символов, начиная от 000001 и заканчивая 999999)
2. всегда строковые,
3. индексировать измерения не получается
(34) BARDER, залоговые билеты имеют сущность? Или просто строки в регистре накопления?
Я бы сделал так:
Отдельный справочник - Залоговые билеты.
И в измерения РН вместо полей (НомерЗалоговогоБилета и СерияЗалоговогоБилета) использовать ссылку справочника.
Тогда достаточно Автоупорядочивание в запросе указать.
(36) spacecraft, вариант не подходит, когда приходывать буду, то мне постоянно нужно будет создавать объект справочника новый, это потом будет большая база, и соответственно весить гигабайты будет
т.е. ориентировочно 200000 билетов в год. за 5 лет только 1 миллион. Это не много. Делайте справочник.
На этом работают современные конфиги от 1С ЕРП2, УТ11, БУХ3. Увеличение производительности в разы, но жуткая проблемма с администрированием. Забудешь - зависнет. Отслеживать надо несуществующие ключи
(44) tusv, не вижу проблемы в администрировании, если правильно делать, а не как делает ТС.
В текущей реализации он заложил не хилую мину замедленного действия. Что будет при перезаписи документа?
а номер должен быть из шести символов, начиная от 000001 и заканчивая 999999)
При таких двнных строковая сортировка не отличается от числовой. Следовательно первые записи можно получить без сортировки с помощью функции МИНИМУМ. Самый простой вариант
ВЫБРАТЬ ПЕРВЫЕ 1
МИНИМУМ(ЗалоговыеБилетыОборотыОстатки.НомерЗалоговогоБилета) Номер,
МИНИМУМ(ЗалоговыеБилетыОборотыОстатки.СерияЗалоговогоБилета) Серия,
ЗалоговыеБилетыОборотыОстатки.Подразделение,
ЗалоговыеБилетыОборотыОстатки.Организация,
ЗалоговыеБилетыОборотыОстатки.КоличествоОстаток
ИЗ
РегистрНакопления.ЗалоговыеБилетыОбороты.Остатки КАК ЗалоговыеБилетыОборотыОстатки
ГДЕ
ЗалоговыеБилетыОборотыОстатки.КоличествоОстаток > 0
СГРУППИРОВАТЬ ПО
ЗалоговыеБилетыОборотыОстатки.Подразделение,
ЗалоговыеБилетыОборотыОстатки.Организация,
ЗалоговыеБилетыОборотыОстатки.КоличествоОстаток
(41) tusv, спасибо, про МИНИМУМ я не сооброзил,
из регистра удалил подразделение, организацию, поставил вместо сортировки МИНИМУМ
на SSD уже 4 секунды обрабатывает, вместо 6.
(42) BARDER,
Существенный прирост производительности. Теперь тупа проиндексируем базу штатними средствами и украдем еще одну секунду:) Для Сиквела это не работает, но для файловой вполне. И на полную катушку
Кроме как индексом ещё как нибудь поднять производительность запроса реально?
Почти не возможно. Теорема:(
Вот такие мои доказательства:
Виртуальная таблица остатков это приблизительно это (Без условий)
ВЫБРАТЬ Измерение1,
Сумма(Ресурс1) КАК Ресурс1
ИЗ (ВЫБРАТЬ(Остатки.Измерение1, Ресурс1
ИЗ ФизическаяТаблицаОстатков
ОБЪЕДИНИТЬ
Измерение1,
ВЫБОР КОГДА Приход ТОГДА
Ресурс1
ИНАЧЕ
-Ресурс1
Конец
ИЗ ФизическаяТаблицаДвижений)
СГРУППИРОВАТЬ ПО Измерение1
В таком случае, ваша архитектура - так себе.
Лучшим (как минимум относительно вашего) решением было бы сделать регистр сведений вида
серия мин номер макс номер:
Ст 000001 999999
СЦ 000001 999999
Этого достаточно, чтобы определять наличие билета
выбрать * из регистр рег где рег.серия=&серия и &номер между рег.МинНомер и рег.МаксНомер
Факт выбытия билета определять по не пустому запросу вида
выбрать * из ДокументВыбытия док где док.СерияБилета = &Серия и док.НомерБилета = &Номер
Если у вас серия и номер в документе выбытия определятся автоматически, по минимуму из имеющихся в наличии (кривоватое решение, как по мне),
то поможет запрос вида
выбрать мин(рег.серия), макс(isnull( док.номерБилета, "000000")) из регистр рег левое соединение документвыбытия док по рег.Серия=док.Серия и рег.МаксНомер <= док.НомерБилета
в результате получис номер последненго выбывшего билета по серии, для определения текущего добавим к нему 1.
Тут желателен индекс по Серия И номерБилета в документе выбытия, но даже если вы его не захотите сделать, работать будет быстрее, чек у вас.
Лучшим (как минимум относительно вашего) решением было бы сделать регистр сведений вида
Нагрузить БД дополнительной таблицей с трудно индексированными полями, к трудно индексированным полям уже имеющей таблице?
Это как бы так
Что то у вас лицо очень довольное, вот вам исчо один мешок, чтобы служба медом не казалось
За что Вы так 1с ненавидите? :(
(57) tusv, чего?
Где вы там увидели трудноиндексируемые поля?
И почему - вдобавок? Остаточный регистр как раз нафиг не нужен.
Вы б попробовали понять для начала написанное, а потом про ненависть говорить.
(60) ditp,
Это Вам так кажется. Строить диапазон со строковыми величинами на строковую величину это лишний мешок на Ваши плечи
Я бы согласился с такой структурой
1 как Номер, 000001 как Представление
Если ЭтотОбъект.Номер = "" Тогда
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| ЗалоговыйБилет.Номер,
| ЗалоговыйБилет.Серия
|ИЗ
| Документ.ЗалоговыйБилет КАК ЗалоговыйБилет
|
|УПОРЯДОЧИТЬ ПО
| ЗалоговыйБилет.Дата УБЫВ";
Результат = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = Результат.Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
НовыйНомер = Строка(Формат(Число(ВыборкаДетальныеЗаписи.Номер)+1, "ЧГ=0"));
КоличествоСимволов = СтрДлина(НовыйНомер);
Пока КоличествоСимволов < 6 Цикл
НовыйНомер = "0" + НовыйНомер;
КоличествоСимволов = КоличествоСимволов +1;
КонецЦикла;
Номер = НовыйНомер;
Серия = ВыборкаДетальныеЗаписи.Серия;
Если НовыйНомер = "1000000" Тогда
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| МИНИМУМ(ЗалоговыеБилетыОборотыОстатки.НомерЗалоговогоБилета) КАК НомерЗалоговогоБилета,
| ЗалоговыеБилетыОборотыОстатки.СерияЗалоговогоБилета КАК СерияЗалоговогоБилета,
| ЗалоговыеБилетыОборотыОстатки.КоличествоОстаток
|ИЗ
| РегистрНакопления.ЗалоговыеБилетыОбороты.Остатки КАК ЗалоговыеБилетыОборотыОстатки
|
|СГРУППИРОВАТЬ ПО
| ЗалоговыеБилетыОборотыОстатки.КоличествоОстаток,
| ЗалоговыеБилетыОборотыОстатки.СерияЗалоговогоБилета";
Результат = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = Результат.Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
Номер = ВыборкаДетальныеЗаписи.НомерЗалоговогоБилета; //НовыйНомерБилета;
Серия = ВыборкаДетальныеЗаписи.СерияЗалоговогоБилета;
КонецЦикла;
КонецЕсли;
КонецЦикла;
ЭтотОбъект.Номер = Номер;
ЭтотОбъект.Серия = Серия;
КонецЕсли;
(56) BARDER,
Это не выход из ситуации. Это ее насилие. Нафига куча циклов, когда доступен Формат?
Например
Формат(112,"ЧЦ=6; ЧН=; ЧВН=; ЧГ=0") Вам вернет "000112"
Тупо нажал на правую кнопку мыши и воспользовался конструктором форматной строки
самое простое всегда приходит в голову в последнюю очередь
Сомое простое Американцы и называют "Знать как" (know how)
Вы хотите автонумерацию с Серией и номером?
Смотрим сюды http://infostart.ru/public/70053/ В шаблоне "АБВГД" цифра 1 равно "А", а цифра 5 равна "АА", цифра 7 равна "АВ" строим документ, где в ПередЗаписью пишем приблизительно
Если префикс изменился тогда
УстановитьНовыйНомер(Новый префикс);
КонецЕсли;
И фсё. Внлосипед придумали за нас, нам нужно научится на нем кататься:)
мне нужно билеты как МЦ делать, тоесть приходовать, далее списывать по мере выдачи займов.
У займа есть Фамилия. Имя, Номер паспорта и другие ключевые поля. То есть имется виртуальный товар со своими индефикационными данными и он уникален. Формировать приход,расход на основе "Бухты барахты" не приемлемо. Это основы предоставления займа. В общем твои работодатели либо придурки, либо Вы их не правильно их поняли. Первый вариант это совсем не вариант. Ибо наше законодательсво снимет шкурку, потом пройдется наждачкой и потом Ваши работодатели поймут, что легко отделались
Топик стартеру нужно знать, какие номера билетов пришли, какие выбыли. Отсюда и списания/приходования. Хотя применительно к его задаче регистр накопления - это из пушки по воробьям.
(69) tusv, у меня есть регистр сведений куда записывается данные залогового билета, ФИО, Номер и серия билета, так же закрыто от редактирования если билет записан, если что то неправильно, то делается испорченным. тут законы уже перечитали все и утвердили печатную форму залогового билета.
У меня есть регистр сведений куда записывается данные залогового билета
Прав автор поста в (70). Я хорошо разбтрась в кредитах и совершенно не знаю Ломбард.
Но черт меня возьми. залоговый документ это документ. Регистры это лишнее, а учет обязан вестись на 002 счете.
Иначе ваш заемщик скажет, что Ви слегка не правы, и таки отдайте кольцо моей матушки и будет прав. И пофигу, что кольца ни когда не было
(74) tusv, а вы представляете выборку остатков из регистра бухгалтерии с таким количеством записей и его "неторопливостью"? так что вполне нормально вести доп. механизм получения остатков отдельно, а в рег бухгалтерии просто писать расход приход - без получения остатков бух итогов
если там количество тупо одно или нисколько, может и запрос не нужен ?
Может просто функцию использовать регистра остатков ?
Пример из СП
Описание:
Получает остатки регистра накопления на заданный момент времени. Есть возможность фильтрации по значениям измерений, а также получения остатков в разрезе других измерений. Возвращает таблицу значений, содержащую колонки с измерениями, указанными в параметре Измерения, и колонки с ресурсами, указанными в параметре <Ресурсы>.
Доступность:
Сервер, толстый клиент, внешнее соединение, мобильное приложение(сервер).
Примечание:
Имеет смысл только для регистров, у которых в Конфигураторе указан вид регистра "Остатки".
Пример:
Остатки = РегистрыНакопления.Остатки;
Фильтр = Новый Структура;
Фильтр.Вставить("Номенклатура",ВыбНоменклатура);
Фильтр.Вставить("Склад", ВыбСклад);
ТабОстатков = Остатки.Остатки(ВыбДата,Фильтр,
"Номенклатура,Склад", "Количество");
Регистры накопления/оборотов работают с хорошей скоростью только когда измерения выборки можно проиндексировать с хорошей селективностью.
Если сделать Серию справочником и билет подчиненным справочником и на измерение билет наложить индекс и сделать его первым в списке измерений - то остатки по билету будут строится не 4 сек, а на порядок меньше - даже на файловой