|
Запрос интервалов последовательности | ☑ | ||
---|---|---|---|---|
0
Valentus
17.01.18
✎
15:46
|
Добрый день. Есть справочник, необходимо сделать объединение в отчете по интервалам кода. Подскажите как правильно написать запрос на таблицу интервалов последовательности кодов справочника(последовательно идущие коды (шаг +1) объединить в интервал)
- код начала последовательности -код конца последовательности Например 1,2,3,4 1-4 6,7,8,9 6-9 Заранее спасибо |
|||
1
azernot
17.01.18
✎
15:48
|
Код в справочнике числовой или текстовый?
|
|||
2
Valentus
17.01.18
✎
16:02
|
Код в справочнике числовой
|
|||
3
azernot
17.01.18
✎
16:06
|
(0) В каком виде заданы интервалы? Строкой через запятую? Или могут быть заданы как-то иначе?
|
|||
4
Valentus
17.01.18
✎
16:12
|
Строкой через запятую 1,2,3,4,5,7,8,9,12,15,16,17,20,25,26,27,28,29
т.е. мне нужно получить 1-5 7-9 12 15-17 20 25-29 |
|||
5
azernot
17.01.18
✎
16:28
|
(4) надо сначала отпарсить эту строку интервалов, динаимчески сформировать текст запроса временной таблицы интервалов (имя интервала, код) и дальше уже соединяться справочником с этой ВТ по коду
Но, куча нюансов.. Что, например, если строка будет такая 29, 28, 27, 14, 15, 16, 1, 2, 3 (т.е. номера не по возрастанию)? или 1-3, 4, 5, 10, 15 (т.е. содержит не только числа и разделитель)? |
|||
6
Valentus
17.01.18
✎
16:31
|
29, 28, 27, 14, 15, 16, 1, 2, 3 (т.е. номера не по возрастанию)?
или 1-3, 4, 5, 10, 15 (т.е. содержит не только числа и разделитель)? номера строго по возрастанию и разделителей не будет. |
|||
7
Valentus
17.01.18
✎
16:33
|
надо сначала отпарсить эту строку интервалов, динаимчески сформировать текст запроса временной таблицы интервалов (имя интервала, код) и дальше уже соединяться справочником с этой ВТ по коду
Как это примерно выглядит в запросе? Я просто руками запросы раньше не писал, обходился конструктором. |
|||
8
Timon1405
17.01.18
✎
16:48
|
если все равно парсить строку зачем тогда потом именно запрос?
|
|||
9
azernot
17.01.18
✎
16:50
|
Вот функция, которая отпарсит строку и выдаст тебе текст генерирующий ВТ_Интервалы
Функция СформироватьТекстЗапросаПоИнтервалам(СтрокаИнтерваловЗаданнаяПользователем) Экспорт НомерИнтервала = 1; МинИнтервала = 0; МаксИнтервала = 0; ПредыдущийКод = Неопределено; Разделитель = ","; СтрокаИнтервалов = СтрокаИнтерваловЗаданнаяПользователем+Разделитель; ТекстЗапросаИнтервалов = ""; Пока СтрНайти(СтрокаИнтервалов, Разделитель)> 0 Цикл ТекКодСтрокой = СокрЛП(Лев(СтрокаИнтервалов,СтрНайти(СтрокаИнтервалов, Разделитель)-1)); СтрокаИнтервалов = Сред(СтрокаИнтервалов,СтрНайти(СтрокаИнтервалов, Разделитель)+1); Если НЕ ЗначениеЗаполнено(ТекКодСтрокой) Тогда Продолжить; КонецЕсли; Попытка ТекКод = Число(ТекКодСтрокой); Исключение //В строке интервалов - не число Возврат ""; КонецПопытки; Если ПредыдущийКод = Неопределено Тогда МинИнтервала = ТекКод; МаксИнтервала = ТекКод; ПредыдущийКод = ТекКод-1; КонецЕсли; Если НЕ ПредыдущийКод+1 = ТекКод Тогда ТекстЗапросаИнтервалов = СтрЗаменить(ТекстЗапросаИнтервалов, "Интервал "+Формат(НомерИнтервала, "ЧГ="), "Интервал "+Формат(МинИнтервала, "ЧГ=")+"-"+Формат(МаксИнтервала, "ЧГ=")); НомерИнтервала = НомерИнтервала+1; МинИнтервала = ТекКод; МаксИнтервала = ТекКод; КонецЕсли; МинИнтервала = Мин(МинИнтервала, ТекКод); МаксИнтервала = Макс(МаксИнтервала, ТекКод); Если ТекстЗапросаИнтервалов = "" Тогда ТекстЗапросаИнтервалов = "Выбрать ""Интервал "+Формат(НомерИнтервала, "ЧГ=")+ """ как ИмяИнтервала, "+Формат(ТекКод, "ЧГ=")+ " как Код"+Символы.ПС + " Поместить ВТ_Интервалы "; Иначе ТекстЗапросаИнтервалов = ТекстЗапросаИнтервалов+ Символы.ПС + " ОБЪЕДИНИТЬ ВСЕ "+Символы.ПС+ "Выбрать ""Интервал "+Формат(НомерИнтервала, "ЧГ=")+ """, "+Формат(ТекКод, "ЧГ="); КонецЕсли; ПредыдущийКод = ТекКод; КонецЦикла; ТекстЗапросаИнтервалов = СтрЗаменить(ТекстЗапросаИнтервалов, "Интервал "+Формат(НомерИнтервала, "ЧГ="), "Интервал "+Формат(МинИнтервала, "ЧГ=")+"-"+Формат(МаксИнтервала, "ЧГ=")); Возврат ТекстЗапросаИнтервалов; КонецФункции У меня на строке из (4) получилось ИмяИнтервала Код Интервал 1 - 5 1 Интервал 1 - 5 2 Интервал 1 - 5 3 Интервал 1 - 5 4 Интервал 1 - 5 5 Интервал 7 - 9 7 Интервал 7 - 9 8 Интервал 7 - 9 9 Интервал 12 - 12 12 Интервал 15 - 17 15 Интервал 15 - 17 16 Интервал 15 - 17 17 Интервал 20 - 20 20 Интервал 25 - 29 25 Интервал 25 - 29 26 Интервал 25 - 29 27 Интервал 25 - 29 28 Интервал 25 - 29 29 Дальше уже можно скомпоновать запрос Запрос.Текст = ТекстЗапросаИнтервалов +";" Запрос.Текст = Запрос.Текст+" "ВЫБРАТЬ | ВТ_Интервалы.ИмяИнтервала КАК ИмяИнтервала, | Склады.Ссылка, | Склады.Код |ИЗ | Справочник.Склады КАК Склады | ЛЕВОЕ СОЕДИНЕНИЕ ВТ_Интервалы КАК ВТ_Интервалы | ПО Склады.Код = ВТ_Интервалы.Код" (я использовал Склады как пример) |
|||
10
Valentus
17.01.18
✎
16:58
|
Большое спасибо! Буду пробовать!
|
|||
11
Valentus
17.01.18
✎
17:16
|
Добавил функцию в модуль, запрос написал, ругается:
Ошибка получения информации набора данных по причине: Ошибка в запросе набора данных по причине: {(7, 20)}: Таблица не найдена "ВТ_Интервалы" ЛЕВОЕ СОЕДИНЕНИЕ <<?>>ВТ_Интервалы КАК ВТ_Интервалы |
|||
12
Valentus
17.01.18
✎
19:00
|
Ругается на временную таблицу ВТ_Интервалы
|
|||
13
azernot
18.01.18
✎
11:06
|
(11) Мда, я в (9) сделал за вас 98% требуемого, вы умудрились запутаться в оставшихся 2%...
Давайте весь код, найдём, где вы ошиблись. ХотяЮ я и так знаю. Вы ошиблись здесь: Запрос.Текст = ТекстЗапросаИнтервалов +";" Запрос.Текст = Запрос.Текст+" "ВЫБРАТЬ | ВТ_Интервалы.ИмяИнтервала КАК ИмяИнтервала, | Склады.Ссылка, | Склады.Код |ИЗ | Справочник.Склады КАК Склады | ЛЕВОЕ СОЕДИНЕНИЕ ВТ_Интервалы КАК ВТ_Интервалы | ПО Склады.Код = ВТ_Интервалы.Код" |
|||
14
Valentus
18.01.18
✎
11:12
|
В общем-то у меня все так же, проверял несколько раз(
Все как у Вас, только справочник у меня Номенклатура. Функция СформироватьТекстЗапросаПоИнтервалам(СтрокаИнтерваловЗаданнаяПользователем) Экспорт НомерИнтервала = 1; МинИнтервала = 0; МаксИнтервала = 0; ПредыдущийКод = Неопределено; Разделитель = ","; СтрокаИнтервалов = СтрокаИнтерваловЗаданнаяПользователем+Разделитель; ТекстЗапросаИнтервалов = "ВТ_Интервалы"; Пока СтрНайти(СтрокаИнтервалов, Разделитель)> 0 Цикл ТекКодСтрокой = СокрЛП(Лев(СтрокаИнтервалов,СтрНайти(СтрокаИнтервалов, Разделитель)-1)); СтрокаИнтервалов = Сред(СтрокаИнтервалов,СтрНайти(СтрокаИнтервалов, Разделитель)+1); Если НЕ ЗначениеЗаполнено(ТекКодСтрокой) Тогда Продолжить; КонецЕсли; Попытка ТекКод = Число(ТекКодСтрокой); Исключение //В строке интервалов - не число Возврат ""; КонецПопытки; Если ПредыдущийКод = Неопределено Тогда МинИнтервала = ТекКод; МаксИнтервала = ТекКод; ПредыдущийКод = ТекКод-1; КонецЕсли; Если НЕ ПредыдущийКод+1 = ТекКод Тогда ТекстЗапросаИнтервалов = СтрЗаменить(ТекстЗапросаИнтервалов, "Интервал "+Формат(НомерИнтервала, "ЧГ="), "Интервал "+Формат(МинИнтервала, "ЧГ=")+"-"+Формат(МаксИнтервала, "ЧГ=")); НомерИнтервала = НомерИнтервала+1; МинИнтервала = ТекКод; МаксИнтервала = ТекКод; КонецЕсли; МинИнтервала = Мин(МинИнтервала, ТекКод); МаксИнтервала = Макс(МаксИнтервала, ТекКод); Если ТекстЗапросаИнтервалов = "ВТ_Интервалы" Тогда ТекстЗапросаИнтервалов = "Выбрать ""Интервал "+Формат(НомерИнтервала, "ЧГ=")+ """ как ИмяИнтервала, "+Формат(ТекКод, "ЧГ=")+ " как Код"+Символы.ПС + " Поместить ВТ_Интервалы "; Иначе ТекстЗапросаИнтервалов = ТекстЗапросаИнтервалов+ Символы.ПС + " ОБЪЕДИНИТЬ ВСЕ "+Символы.ПС+ "Выбрать ""Интервал "+Формат(НомерИнтервала, "ЧГ=")+ """, "+Формат(ТекКод, "ЧГ="); КонецЕсли; ПредыдущийКод = ТекКод; КонецЦикла; ТекстЗапросаИнтервалов = СтрЗаменить(ТекстЗапросаИнтервалов, "Интервал "+Формат(НомерИнтервала, "ЧГ="), "Интервал "+Формат(МинИнтервала, "ЧГ=")+"-"+Формат(МаксИнтервала, "ЧГ=")); Возврат ТекстЗапросаИнтервалов; КонецФункции Запрос.Текст = ТекстЗапросаИнтервалов +";" Запрос.Текст = Запрос.Текст+" "ВЫБРАТЬ | ВТ_Интервалы.ИмяИнтервала КАК ИмяИнтервала, | Номенклатура.Ссылка, | Номенклатура.Код |ИЗ | Справочник.Номенклатура КАК Номенклатура | ЛЕВОЕ СОЕДИНЕНИЕ ВТ_Интервалы КАК ВТ_Интервалы | ПО Номенклатура.Код = ВТ_Интервалы.Код" |
|||
15
azernot
18.01.18
✎
12:04
|
(14) Значит у вас на момент компоновки запроса не заполнена переменная ТекстЗапросаИнтервалов.
Т.е. вы не вызываете собственно функцию, или она возвращает пустую строку (например, потому что не может преобразовать значение в число). Приведите полный код, как инициируете запрос, как компонуете текст, как выполняете. И укажите строку интервалов, заданную пользователем. |
|||
16
azernot
18.01.18
✎
12:09
|
(14) А это что?!
ТекстЗапросаИнтервалов = "ВТ_Интервалы"; Что за самоуправство? :) Именно это изменение приводит к проблеме! |
|||
17
azernot
18.01.18
✎
12:11
|
+(16) Хотя нет, вы и дальше поправили.. только смысл не понятен. Ну да ладно. нужен полный код.
|
|||
18
Valentus
18.01.18
✎
13:14
|
Запрос я добавил через СКД а функцию в модуль объекта отчета, там больше ничего нет.
не заполнена переменная ТекстЗапросаИнтервалов - я правильно понимаю что запрос не может найти временную таблицу ВТ_Интервалы и необходимо в модуле добавить Перем? |
|||
19
azernot
18.01.18
✎
13:29
|
(18) Боюсь, я вынужден признать, что вашего уровня компетенции на текущий момент недостаточно, чтобы решить поставленную задачу. Делать это ЗА вас я не буду (во всяком случае бесплатно), а для того, чтобы вам помочь - вы должны задавать вопросы. А этого вы сделать не можете, поскольку не понимаете что и как вы должны сделать.
Мало того, судя по всему, вы не понимаете базовых принципов работы запросов с временными таблицами, не знаете принципы работы схемы компоновки данных, а эти знания просто необходимы, потому как простым конструктором запроса в отчёте на СКД здесь не обойтись. Вам нужно фактически при компоновке результата внести изменения в схему: получить строку интервалов заданную пользователем, выполнить мой функцию и получить запрос по формированию таблицы интервалов, внести изменения в источник данных СКД (поместить туда запрос по формированию временной таблицы интервалов) или каким-то иным образом передать в СКД таблицу интервалов, чтобы с ней соединить свой справочник. |
|||
20
Ненавижу 1С
гуру
18.01.18
✎
13:34
|
ВЫБРАТЬ
1 КАК Ч ПОМЕСТИТЬ Т ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ 2 ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ 3 ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ 4 ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ 6 ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ 7 ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ 8 ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ 9 ; //////////////////////////////////////////////////////////////////////////////// ВЫБРАТЬ Т.Ч ПОМЕСТИТЬ ЛТ ИЗ Т КАК Т ЛЕВОЕ СОЕДИНЕНИЕ Т КАК Т1 ПО (Т.Ч = Т1.Ч + 1) ГДЕ Т1.Ч ЕСТЬ NULL ; //////////////////////////////////////////////////////////////////////////////// ВЫБРАТЬ Т.Ч ПОМЕСТИТЬ ПТ ИЗ Т КАК Т ЛЕВОЕ СОЕДИНЕНИЕ Т КАК Т1 ПО (Т.Ч = Т1.Ч - 1) ГДЕ Т1.Ч ЕСТЬ NULL ; //////////////////////////////////////////////////////////////////////////////// ВЫБРАТЬ ЛТ.Ч, МИНИМУМ(ПТ.Ч) КАК Ч1 ИЗ ЛТ КАК ЛТ ЛЕВОЕ СОЕДИНЕНИЕ ПТ КАК ПТ ПО ЛТ.Ч <= ПТ.Ч СГРУППИРОВАТЬ ПО ЛТ.Ч |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |