Работа со строками в запросе

К сожалению, возможности запросов 1С в отношении строковых переменных крайне малы. Практически они исчерпываются одной функцией и одним оператором. Тем не менее, постоянно всплывают темы в духе «а как мне сделать это прямо в запросе?». Конечно, большинство задач решаются в СКД, оставшаяся часть решается пост-обработкой результата, но чисто в качестве разминки для ума, кое-что в запросе сделать можно.

Только ленивый, по-моему, не писал еще о вариантах вырезания гланд через анус автогеном запросами. Ну и я поделюсь.

 

К сожалению, возможности запросов 1С в отношении строковых переменных крайне малы. Практически они исчерпываются одной функцией и одним оператором. Тем не менее, постоянно всплывают темы в духе «а как мне сделать это прямо в запросе?». Конечно, большинство задач решаются в СКД, оставшаяся часть решается пост-обработкой результата, но чисто в качестве разминки для ума, кое-что в запросе сделать можно.

 

Во всех примерах я буду использовать следующие временные таблицы:

ВЫБРАТЬ
    «_» КАК Симв,
   
1 КАК КолСимв
ПОМЕСТИТЬ тзКоличествоСимволов9
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
    «__»,
   
2
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
    «___»,
   
3
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
    «____»,
   
4
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
    «_____»,
   
5
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
    «______»,
   
6
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
    «_______»,
   
7
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
    «________»,
   
8
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
    «_________»,
   
9
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
    «»,
   
0
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    тзКоличествоСимволов9_Лев.Симв + тзКоличествоСимволов9_Лев.Симв + тзКоличествоСимволов9_Лев.Симв + тзКоличествоСимволов9_Лев.Симв + тзКоличествоСимволов9_Лев.Симв + тзКоличествоСимволов9_Лев.Симв + тзКоличествоСимволов9_Лев.Симв + тзКоличествоСимволов9_Лев.Симв + тзКоличествоСимволов9_Лев.Симв + тзКоличествоСимволов9_Лев.Симв + тзКоличествоСимволов9_Прав.Симв КАК Симв,
   
тзКоличествоСимволов9_Лев.КолСимв * 10 + тзКоличествоСимволов9_Прав.КолСимв КАК КолСимв
ПОМЕСТИТЬ тзКоличествоСимволов100
ИЗ
   
тзКоличествоСимволов9 КАК тзКоличествоСимволов9_Лев,
   
тзКоличествоСимволов9 КАК тзКоличествоСимволов9_Прав
;
////////////////////////////////////////////////////////////////////////////////

Для приведенных примеров их вполне хватит, смысл, думаю, понятен, так что не будем заострять внимание на оптимальности их построения.

 

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

  1. Подсчет количества символов в строке.

 Тут всё очень просто

ВЫБРАТЬ
    Номенклатура.Наименование,
   
КоличествоСимволов.КолСимв
ИЗ
   
Справочник.Номенклатура КАК Номенклатура
        ЛЕВОЕ СОЕДИНЕНИЕ тзКоличествоСимволов100 КАК КоличествоСимволов
        ПО (Номенклатура.Наименование ПОДОБНО КоличествоСимволов.Симв)

Всё. Теперь можно отрезать последний пробел, например:

ВЫБРАТЬ
    Номенклатура.Наименование,
   
КоличествоСимволов.КолСимв,
   
ВЫБОР
        КОГДА Наименование подобно «% «
           
ТОГДА ПОДСТРОКА(Номенклатура.Наименование, 1, КоличествоСимволов.КолСимв 1)
        ИНАЧЕ
Номенклатура.Наименование
    КОНЕЦ КАК НаименованиеБезПробела
ИЗ
   
Справочник.Номенклатура КАК Номенклатура
        ЛЕВОЕ СОЕДИНЕНИЕ тзКоличествоСимволов100 КАК КоличествоСимволов
        ПО (Номенклатура.Наименование ПОДОБНО КоличествоСимволов.Симв)

 

      2. Разбить строку

Здесь чуть сложнее. Но теми же граблями.

Задача: в некоторой номенклатуре в наименовании записан некоторый текст в скобках. Надо вытащить этот текст в отдельное поле.

Для простоты договоримся, что скобочки в наименовании у нас один раз открываются и один раз закрываются.

ВЫБРАТЬ Различные
    Номенклатура.Ссылка,
   
Выразить(ПОДСТРОКА(Номенклатура.Наименование, КоличествоСимволовДоОткрытия.КолСимв+2, КоличествоСимволовДоЗакрытия.КолСимвКоличествоСимволовДоОткрытия.КолСимв1) как строка(100)) КАК ТекстВСкобках
ИЗ
   
Справочник.Номенклатура КАК Номенклатура
        ЛЕВОЕ СОЕДИНЕНИЕ тзКоличествоСимволов100 КАК КоличествоСимволовДоОткрытия
        ПО (Номенклатура.Наименование ПОДОБНО КоличествоСимволовДоОткрытия.Симв + &СимволОткрытия + «%»)
       
ЛЕВОЕ СОЕДИНЕНИЕ тзКоличествоСимволов100 КАК КоличествоСимволовДоЗакрытия
        ПО (Номенклатура.Наименование ПОДОБНО КоличествоСимволовДоЗакрытия.Симв + &СимволЗакрытия + «%»)
ГДЕ
    Номенклатура.Наименование ПОДОБНО «%» + &СимволОткрытия + «%» + &СимволЗакрытия + «%»

Тут &СимволОткрытия, понятно «(»,&СимволЗакрытия соответственно «)». Находим позицию символов и вытаскиваем подстроку. Помним, что запросы тошнит от строк неограниченной длины, поэтому используем ВЫРАЗИТЬ.

  

      3. Сложное соединение по строке.

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

Существуют две таблицы:

В одной номера договоров в формате: «Номер-постфикс»

В другой номера тех же договоров, но дополненные неким доп-индексом в формате: «Номер/Индекс-постфикс».

Необходимо связать. Номер, индекс и постфикс могут быть разной длины, ориентироваться можно только на «/» и «-».

 

Сымитируем данные:

Выбрать
«30568-12» как ВнутреннийНомер
поместить тз1
Объединить все
Выбрать
«3568-12»
;
Выбрать
«30568/1-12» как ВнутреннийНомер
поместить тз2
Объединить все
Выбрать
«30568/155-12»
Объединить все
Выбрать
«30568/2-12»
Объединить все
Выбрать
«35681/2-12»
Объединить все
Выбрать
«3568/2-12»
Объединить все
Выбрать
«3568/2-13»
;

И начнем выпендриваться.

//Выделим из номеров те части, по которым сможем связывать
Выбрать
тз1сРазбиением.ВнутреннийНомер,
Подстрока(тз1сРазбиением.ВнутреннийНомер,1, КоличествоСимволовДоТире.КолСимв) как ДоСлэша,
Подстрока(тз1сРазбиением.ВнутреннийНомер,КоличествоСимволовДоТире.КолСимв+2, СтрДлина.КолСимв) как ПослеТире
поместить тз1сРазбиением
из тз1 как тз1сРазбиением
    ЛЕВОЕ СОЕДИНЕНИЕ тзКоличествоСимволов100 КАК КоличествоСимволовДоТире
    ПО (тз1сРазбиением.ВнутреннийНомер ПОДОБНО КоличествоСимволовДоТире.Симв+«-%»)
   
ЛЕВОЕ СОЕДИНЕНИЕ тзКоличествоСимволов100 КАК СтрДлина
    ПО (тз1сРазбиением.ВнутреннийНомер ПОДОБНО СтрДлина.Симв)
;
Выбрать
тз2сРазбиением.ВнутреннийНомер,
Подстрока(тз2сРазбиением.ВнутреннийНомер,1, КоличествоСимволовДоСлэша.КолСимв) как ДоСлэша,
Подстрока(тз2сРазбиением.ВнутреннийНомер,КоличествоСимволовДоТире.КолСимв+2, СтрДлина.КолСимв) как ПослеТире
поместить тз2сРазбиением
из тз2 как тз2сРазбиением
    ЛЕВОЕ СОЕДИНЕНИЕ тзКоличествоСимволов100 КАК КоличествоСимволовДоСлэша
    ПО (тз2сРазбиением.ВнутреннийНомер ПОДОБНО КоличествоСимволовДоСлэша.Симв+«/%»)
   
ЛЕВОЕ СОЕДИНЕНИЕ тзКоличествоСимволов100 КАК КоличествоСимволовДоТире
    ПО (тз2сРазбиением.ВнутреннийНомер ПОДОБНО КоличествоСимволовДоТире.Симв+«-%»)
   
ЛЕВОЕ СОЕДИНЕНИЕ тзКоличествоСимволов100 КАК СтрДлина
    ПО (тз2сРазбиением.ВнутреннийНомер ПОДОБНО СтрДлина.Симв)
;

ВЫБРАТЬ Различные
    тз11.ВнутреннийНомер,
   
тз22.ВнутреннийНомер
ИЗ
   
тз1сРазбиением КАК тз11
        Левое СОЕДИНЕНИЕ тз2сРазбиением КАК тз22
        ПО тз11.ДоСлэша Подобно тз22.ДоСлэша
        и  тз11.ПослеТире Подобно тз22.ПослеТире

 

    Для любителей возмущающаться напомню, что целью было отвлечься от работы J Если кому-то пригодится в практических целях, буду рада.


50 Comments

  1. andrewks

    Временные таблицы со строками и куча ПОДОБНО ?

    да это просто издевательство над скулем какое-то

    Reply
  2. andrewks

    определяем длину строки:

    select
    &Парам1 as str
    into ВходнаяВТ
    
    ;
    // здесь создаём ВТ цифр
    
    select
    0 as num
    into digits
    union select 1 union select 2 union select 3 union select 4 union select 5
    union select 6 union select 7 union select 8 union select 9
    
    ;
    // здесь создаём ВТ чисел
    
    select
    digits1.num+10*digits2.num+100*digits3.num as num
    into numbers
    from
    digits as digits1
    ,digits as digits2
    ,digits as digits3
    index by num
    
    ;
    
    // здесь определяем макс.позицию символа (т.е. длину строки)
    
    select
    tabstr.str
    ,max(numbers.num) as maxpos
    from
    ВходнаяВТ as tabstr
    ,numbers
    where (substring(tabstr.str,numbers.num,1)<>»»)
    group by
    tabstr.str
    
    
    

    Показать

    Reply
  3. andrewks

    здесь выделяем из строки то, что в скобках:

    select
    &Парам1 as str
    into ВходнаяВТ
    
    ;
    // здесь создаём ВТ цифр
    
    select
    0 as num
    into digits
    union select 1 union select 2 union select 3 union select 4 union select 5
    union select 6 union select 7 union select 8 union select 9
    
    ;
    // здесь создаём ВТ чисел
    
    select
    digits1.num+10*digits2.num+100*digits3.num as num
    into numbers
    from
    digits as digits1
    ,digits as digits2
    ,digits as digits3
    index by num
    
    ;
    
    // здесь определяем макс.символ
    
    select
    tabstr.str
    ,max(numbers.num) as maxpos
    into
    ВходнаяВТ2
    from
    ВходнаяВТ as tabstr
    ,numbers
    //where (substring(tabstr.str,numbers.num,1)<>»») and (substring(tabstr.str,numbers.num,1)<>» «)
    where (substring(tabstr.str,numbers.num,1)=»)»)
    group by
    tabstr.str
    
    ;
    
    // здесь разбираем входную строку
    
    select
    substring(tabstr.str,1,numbers.num-1) as pred1
    ,substring(tabstr.str,numbers.num+1,tabstr.maxpos-numbers.num-1) as pred2
    from
    ВходнаяВТ2 as tabstr
    left join
    numbers
    on (numbers.num>0) and (substring(tabstr.str,numbers.num,1)=»(«)
    
    
    

    Показать

    Reply
  4. andrewks

    3. Сложное соединение по строке.

    Ну и совсем извращение,

    действительно, извращение ))

    собственно, делается по аналогии, тут уже лень

    Reply
  5. andrewks

    да, вот ещё в копилку: выбор строки с макс.длиной

    select
    «строка 1» as str
    into tabstr
    union all
    select «строка № 45678»
    union all
    select «а это, похоже, самая длинная строка»
    
    ;
    
    select
    0 as num
    into digits
    union select 1 union select 2 union select 3 union select 4 union select 5
    union select 6 union select 7 union select 8 union select 9
    
    ;
    
    select
    digits1.num+10*digits2.num+100*digits3.num+1000*digits4.num as num
    into numbers
    from
    digits as digits1
    ,digits as digits2
    ,digits as digits3
    ,digits as digits4
    index by num
    
    ;
    
    select
    tabstr.str as str
    ,max(numbers.num) as length
    into tabstr2
    from
    tabstr
    ,numbers
    where (substring(tabstr.str,numbers.num,1)>»»)
    group by
    tabstr.str
    
    ;
    
    select
    max(tabstr.length) as length
    into maxlength
    from
    tabstr2 as tabstr
    
    ;
    
    select
    tabstr.str as str
    from
    tabstr2 as tabstr
    right join
    maxlength
    on (tabstr.length=maxlength.length)
    
    

    Показать

    Reply
  6. andrewks

    здесь определяем последний (самый правый) символ строки и его позицию:

    select
    &Парам1 as str
    into ВходнаяВТ
    
    ;
    // здесь создаём ВТ цифр, их строковых представлений, и соответствующих степеней десяток
    
    select
    0 as num
    ,»0″ as numstr
    into digits
    union select 1,»1″ union select 2,»2″ union select 3,»3″ union select 4,»4″ union select 5,»5″
    union select 6,»6″ union select 7,»7″ union select 8,»8″ union select 9,»9″
    
    ;
    // здесь создаём ВТ чисел и их строковых представлений
    
    select
    digits1.num+10*digits2.num as num
    ,digits2.numstr+digits1.numstr as numstr
    into numbers
    from
    digits as digits1
    ,digits as digits2
    index by num,numstr
    
    ;
    // здесь разбираем входную строку, оставляем только символы, которые могут быть в представлении числа
    
    select
    substring(tabstr.str,numbers.num,1) as symb
    ,numbers.num as pos
    into symbstr
    from
    ВходнаяВТ as tabstr
    left join
    numbers
    on (numbers.num>0) and (substring(tabstr.str,numbers.num,1)>»»)
    index by symb,pos
    
    ;
    
    // здесь нумеруем символы «чистой» строки с правой стороны
    
    select
    symbstr.symb as symb
    ,symbstr.pos as pos
    ,count(symbstr.pos) as ind
    into symbols
    from
    symbstr
    inner join symbstr as symbstr1
    on (symbstr.pos<=symbstr1.pos)
    group by
    symbstr.symb
    ,symbstr.pos
    //order by ind
    index by ind
    
    ;
    select top 1
    symbols.symb
    ,symbols.pos
    from
    symbols
    order by
    pos desc
    

    Показать

    Reply
  7. Поручик

    (2) По-русски сложно написать? Обязательно свои понты дешёвые показать.

    Reply
  8. catena

    (1)Ага 🙂

    (2)На серверной базе моя длина строки работает в полтора раза быстрее(на справочнике 18000 элементов) На файловой в 7 раз(28 секунд против 4). 🙂 И пустые строки ваш запрос игнорирует, исключает из выборки как класс.

    А в остальном да, скуль мои запросы не ест 🙂

    Reply
  9. catena

    Хотя на файловой мои все-таки быстрее )))

    Reply
  10. andrewks

    (7) Поручик, о чём Вы, сударь? какие понты? я всегда так пишу. а кто органически неприемлет английский и/или sql-ный синтаксис тех смиренно прошу мои посты игнорировать

    Reply
  11. andrewks

    (9) зато на серверных Ваши могут вообще упасть. вот за DB2, в частности, я очень не уверен, на этой СУБД 1с-вское ПОДОБНО зело глючит

    Reply
  12. andrewks

    (8) а пустые строки зачем обрабатывать? хотя, и это можно предусмотреть

    Reply
  13. andrewks

    (8) как замеры производили?

    Reply
  14. catena

    (11)Я и говорю, что падают. Хотя странно, оракл, например, вроде хорошо работает с like’ом.

    Я не отрицаю, что намудрила, но вы же тоже не делитесь знаниями 🙂 Вот про скобки девушка летом вопрошала на форуме и ей в один голос заявили, что в запросе никак. Теперь хоть в поиске будет 🙂 Да и сложное соединение — реальный пример.

    (12)Ну чтобы было. Для порядку. Эт я придираюсь.

    Reply
  15. catena

    (13)В консоли с «WINMM.DLL», «timeGetTime»

    Reply
  16. andrewks

    (15) если не забуду, сегодня на работе постараюсь сравнить время моих и Ваших запросов, отпишусь

    Reply
  17. andrewks
    но вы же тоже не делитесь знаниями

    лично я всегда делюсь, если встречаю. я эти строки в запросах долго крутил. даже где-то валяется текст по переводу дробного числа из текстового представления в числовое в запросе

    Reply
  18. kasper076

    Вот так сделал недавно:

    ВЫБОР
    КОГДА ПОДСТРОКА(СписокНоменклатуры.Код, 1, 6) = «000000»
    ТОГДА ВЫБОР
    КОГДА ПОДСТРОКА(СписокНоменклатуры.Код, 7, 4) = «0000»
    ТОГДА »          » + ПОДСТРОКА(СписокНоменклатуры.Код, 11, 1)
    КОГДА ПОДСТРОКА(СписокНоменклатуры.Код, 7, 3) = «000»
    ТОГДА »         » + ПОДСТРОКА(СписокНоменклатуры.Код, 10, 2)
    КОГДА ПОДСТРОКА(СписокНоменклатуры.Код, 7, 2) = «00»
    ТОГДА »        » + ПОДСТРОКА(СписокНоменклатуры.Код, 9, 3)
    КОГДА ПОДСТРОКА(СписокНоменклатуры.Код, 7, 1) = «0»
    ТОГДА »       » + ПОДСТРОКА(СписокНоменклатуры.Код, 8, 4)
    ИНАЧЕ »      » + ПОДСТРОКА(СписокНоменклатуры.Код, 7, 5)
    КОНЕЦ
    ИНАЧЕ ВЫБОР
    КОГДА ПОДСТРОКА(СписокНоменклатуры.Код, 1, 5) = «00000»
    ТОГДА »     » + ПОДСТРОКА(СписокНоменклатуры.Код, 6, 6)
    КОГДА ПОДСТРОКА(СписокНоменклатуры.Код, 1, 4) = «0000»
    ТОГДА »    » + ПОДСТРОКА(СписокНоменклатуры.Код, 5, 7)
    КОГДА ПОДСТРОКА(СписокНоменклатуры.Код, 1, 3) = «000»
    ТОГДА »   » + ПОДСТРОКА(СписокНоменклатуры.Код, 4, 8)
    КОГДА ПОДСТРОКА(СписокНоменклатуры.Код, 1, 2) = «00»
    ТОГДА »  » + ПОДСТРОКА(СписокНоменклатуры.Код, 3, 9)
    КОГДА ПОДСТРОКА(СписокНоменклатуры.Код, 1, 1) = «0»
    ТОГДА » » + ПОДСТРОКА(СписокНоменклатуры.Код, 2, 10)
    ИНАЧЕ СписокНоменклатуры.Код
    КОНЕЦ
    КОНЕЦ

    Показать

    Reply
  19. andrewks

    (15) сразу не разглядел, но причина в том, что у меня макс.длина строки определяется в 1000, у Вас — всего в 100

    если переопределить данную табличку

    select
    digits1.num+10*digits2.num as num
    into numbers
    from
    digits as digits1
    ,digits as digits2
    index by num
    
    

    Показать

    , то, естественно, получаются совершенно другие временные результаты

    Reply
  20. andrewks

    (18) kasper076, угу, а теперь попробуйте переписать для кода, скажем, длиной в 15 символов

    Reply
  21. kasper076

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

    Reply
  22. catena

    (19)Да действительно, я тоже не обратила на это внимания. Минус одно соединение.

    Reply
  23. catena

    Агрегатной функции конкатенации все-таки оченно не хватает.

    Reply
  24. andrewks

    (23) Вы не про это?

    select
    &Парам1+&Парам2 as str
    
    

    🙂

    Reply
  25. andrewks

    (22) как я и ожидал, Ваш вариант разбивки строки в DB2 не отрабатывает. а мой — отрабатывает 😉

    Reply
  26. Ёпрст

    чего только не придумают, и всё от того, что язык запросов в снеговике недоделан

    :((

    ЗЫ: про доп табличку с циферками, обычно есть куча примеров в любой книжке по sql..

    Reply
  27. catena

    (25)Я это еще утром признала.

    (24)Не, я про группировки. Например, в оракле я могу так:

    with Str as (

    select

    ‘fff’ f1 from dual

    union all

    select

    ‘yyy’ from dual

    union all

    select

    ‘rrr’ from dual

    )

    select wmsys.wm_concat(Str.f1) from Str

    Reply
  28. andrewks

    (26) Ёпрст, угу, 1С — виновница очень многих извращений

    Reply
  29. andrewks

    (27) ну, в mssql тоже много чего можно, вплоть до итераций

    Reply
  30. Ёпрст

    (27) в sqllite тоже есть group by concat

    Reply
  31. andrewks

    а всё почему: потому, что


    ПОДОБНО при использовании DB2

    Проблема:

    В клиент-серверном варианте работы, при использовании СУБД IBM DB2, в запросах, содержащих операцию ПОДОБНО и выражение (а не фиксированную строку) справа от операции, может происходить ошибка и сервер СУБД аварийно завершает свою работу.

    Способы решения:

    Использовать DB2 9.7 FixPack5

    Дата публикации: 2012-04-10

    причём, в фикспаке сервак просто не рушится, но результат пустой

    Reply
  32. andrewks

    да бог с ним, с конкатом. лично меня бы очень устроили хотя бы нормальные реализации cast’ов и коррелированных подзапросов

    Reply
  33. DrAku1a

    Извращенцы… 🙂

    Reply
  34. catena

    (28)Зато ничего не страшно 🙂 Когда мне понадобилось быстро научиться читать/писать простейшие оракловые запросы, я для тренировки переводила отрисовку календаря из какой-то местной статьи, а потом доводила до инфаркта получившимся кодом местных ораклистов 🙂

    Reply
  35. Painted

    (7) Поручик, Я даже не сразу понял, что текст английский. Сначала забрасываю все в Консоль запросов, а там код преобразуется в русский на автомате. ))))

    Reply
  36. Yashazz

    (26) В смысле строковых операций в запросе много где недоделано. Я вот не знаю, есть ли диалекты, понимающие регулярные выражения в запросе скуля, так что не надо обижать снеговика. С возвращением возможности втыкать общие функции в СКД уже очень много что можно, хотя и транслируется извратно.

    Вообще не понимаю я, зачем такие грабли. Только из желания поковыряться ногой в носу, или есть-таки практическое применение? Имхо, грамотно организованные структуры данных и код алгоритмов никто не отменял.

    Reply
  37. CaSH_2004

    (0) В итоге получаем нечитабельный запрос а’ля обфускация. К чему это? Смахивает на софистику т.е. игра словами ради игры. Думаю такие статьи должны сопровождаться знаком «Только для извращенцев которые все перепробовали». Если такие операции приводят к существенному увеличению производительности то конечно оно того стоит, но вроде об этом как то смутно сказано только в комментариях.

    Reply
  38. aspirator23

    А как соединить в запросе строковое поле и поле даты?

    Что-то такое:

    ТекстЗапроса=

    …..

    Документ.Номер+» от «+Документ.Дата

    ….

    Через Выразить, подстрока.. не получается.

    Reply
  39. Bukaska

    Извините за вопрос, а какое объединение можно использовать в 1С? А то я слышала что в СКД как с объединениями ни крути — 1С всё переделает как левое внутреннее…

    Reply
  40. catena

    (38)На прямую — никак. Можно дату выразить как строку, тоже то еще извращение.

    (39)В языке запросов можно использовать любые соединения. В СКД соединения между наборами данных осуществляются левыми соединениями, а в запросе так же можно организовать любое.

    Reply
  41. OlenkaD

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

    Например: Номенклатура 1 арт Х-1234

    Номенклатура 2 арт Х-1233

    Номенклатура 3 арт Х-1243

    минимальная длина артикула, которая должна совпадать = 4

    Reply
  42. andrewks

    (41) OlenkaD, используйте ПОДОБНО

    Reply
  43. OlenkaD

    Получился такой запрос:

    ВЫБРАТЬ

    СвободныеОстаткиОстатки.Номенклатура,

    СвободныеОстаткиОстатки.ВНаличииОстаток КАК ПоложитОстаток,

    СвободныеОстаткиОстатки.Номенклатура.Артикул

    ПОМЕСТИТЬ ПоложительныеОстатки

    ИЗ

    РегистрНакопления.СвободныеОстатки.Остатки(, Склад = &Склад) КАК СвободныеОстаткиОстатки

    ГДЕ

    СвободныеОстаткиОстатки.ВНаличииОстаток > 0

    ;

    ////////////////////////////////////////////////////////////­////////////////////

    ВЫБРАТЬ

    СвободныеОстаткиОстатки.Номенклатура,

    СвободныеОстаткиОстатки.ВНаличииОстаток КАК ОтрицатОстаток,

    СвободныеОстаткиОстатки.Номенклатура.Артикул

    ПОМЕСТИТЬ ОтрицательныеОстатки

    ИЗ

    РегистрНакопления.СвободныеОстатки.Остатки(, Склад = &Склад) КАК СвободныеОстаткиОстатки

    ГДЕ

    СвободныеОстаткиОстатки.ВНаличииОстаток < 0

    ;

    ////////////////////////////////////////////////////////////­////////////////////

    ВЫБРАТЬ

    ПоложительныеОстатки.НоменклатураАртикул КАК АртикулПоложит,

    ПоложительныеОстатки.Номенклатура КАК НоменклатураПоложит,

    ПоложительныеОстатки.ПоложитОстаток,

    ОтрицательныеОстатки.НоменклатураАртикул КАК АртикулОтрицат,

    ОтрицательныеОстатки.Номенклатура КАК НоменклатураОтрицат,

    ОтрицательныеОстатки.ОтрицатОстаток

    ИЗ

    ПоложительныеОстатки КАК ПоложительныеОстатки

    ВНУТРЕННЕЕ СОЕДИНЕНИЕ ОтрицательныеОстатки КАК ОтрицательныеОстатки

    ПО (ПОДСТРОКА(ОтрицательныеОстатки.НоменклатураАртикул, 1, &Длина) ПОДОБНО ПОДСТРОКА(ПоложительныеОстатки.НоменклатураАртикул, 1, &Длина))

    Теперь задача такая: параметр &Длина зависит от кол-ва символов в

    ПоложительныеОстатки.Номенклатура КАК НоменклатураПоложит и может принимать значения от N (кол-во символов в этом поле) до &МинДлинаАртикула (которая заранее известна)

    Как это можно реализовать в запросе?

    Reply
  44. OlenkaD

    Думается что то подобное написать:

    Выбор когда ПоложительныеОстатки.НоменклатураАртикул = ОтрицательныеОстатки.НоменклатураАртикул Тогда

    ОтрицательныеОстатки.НоменклатураАртикул

    Иначе

    Выбор когда

    (ПОДСТРОКА(ОтрицательныеОстатки.НоменклатураАртикул, 1, &Длина) ПОДОБНО

    ПОДСТРОКА(ПоложительныеОстатки.НоменклатураАртикул, 1, &Длина)) Тогда

    ПОДСТРОКА(ОтрицательныеОстатки.НоменклатураАртикул, 1, &Длина)

    Конец

    Конец

    Вопрос: как задавать параметр &Длина и считать длину строки прямо в запросе? (аналог СтрДлина)

    Reply
  45. OlenkaD

    Заморочилась так:

    Когда Наименование = ПОДСТРОКА ( Наименование,1, 90) Тогда 90

    Когда Наименование = ПОДСТРОКА ( Наименование,1, 91) Тогда 91

    Когда Наименование = ПОДСТРОКА ( Наименование,1, 92) Тогда 92

    Когда Наименование = ПОДСТРОКА ( Наименование,1, 93) Тогда 93

    Когда Наименование = ПОДСТРОКА ( Наименование,1, 94) Тогда 94

    Когда Наименование = ПОДСТРОКА ( Наименование,1, 95) Тогда 95

    Когда Наименование = ПОДСТРОКА ( Наименование,1, 96) Тогда 96

    Reply
  46. Persempre

    Клуб извращенцов

    Reply
  47. sss999

    (6) andrewks, (30) Ёпрст, а как посчитать длину строки в 1с 77 в прямом запросе,или хотя бы сравнить на равенство длины два значения

    Reply
  48. catena

    (47)А разве в прямых запросах недоступны функции скл?

    Reply
  49. sss999

    (48) они доступны если база на скуле,а если dbf то синтаксис фокс про и там по своему это все.

    Reply
  50. Светлый ум

    (35) Зачетный лайфхак +1

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *