Имя: Пароль:
1C
1C 7.7
v7: Знатокам 1с++
0 mishaPH
 
22.01.24
18:55
В общем есть 7ка ТИС 9хх где есть спр Контрагенты и у него юрфизлицо типа"Справочник" без уточнения.
И надо у этого юрфизлица получить ИНН.

поскольку сделать join в лоб не выйдет т.к. справочник неизвестный, ломаю голову как это сделать.

Запрос по заказам и надо получить ИНН юрфизлица.
на форуме по 1с++ дали образец, но не работает. ругается.

Вот запрос и вставка по рекомендации с форума.

ругается,

State 42000, native 195, message [Microsoft][ODBC SQL Server Driver][SQL Server]'length' is not a recognized built-in function name.

если строку length закомментировать то
State 42000, native 195, message [Microsoft][ODBC SQL Server Driver][SQL Server]'Substr' is not a recognized built-in function name.

    рс = СоздатьОбъект("ODBCRecordset");    
    ТекстЗапроса = "
    |SELECT ЗаявкаПокупателя.IDDOC [ЗаявкаПокупателя $Документ.ЗаявкаПокупателя]
    |    , Журнал.$ОбщийРеквизит.Автор [Автор $Справочник.Пользователи]
    |    , $ЗаявкаПокупателя.Контрагент [Кон $Справочник.Контрагенты]
    |    , $ЗаявкаПокупателя.ДатаОтгрузки Дата
    |    , $ЗаявкаПокупателяСтроки.Номенклатура [Ном $Справочник.Номенклатура]
    |    , $ЗаявкаПокупателяСтроки.Количество Количество
    |   , Номенклатура.Code КодНом
    |   , Контрагенты.Code КодКон
    |
    //|   , Контрагенты.ЮрФизЛицо [ЮрФизЛицо $Справочник]
    //|    , Контрагенты.ЮрФизЛицо AS ЮрФизЛицоСтрока
    //|    ,$ВидСправочника36.ЮрЛица
    //|    ,length($ВидСправочника36.ЮрЛица)
    |    ,CASE
    |        WHEN Substr(Контрагенты.ЮрФизЛицо, 1, 4) = $ВидСправочника36.ЮрЛица THEN 'ЮрЛица'
    |        WHEN Substr(Контрагенты.ЮрФизЛицо, 1, 4) = $ВидСправочника36.ФизЛица THEN 'ФизЛица'
    |        ELSE 'Не определен'
    |    END AS Вид
    |    ,COALESCE(СпрЮЛ.ЮрАдрес,СпрФЛ.ЮрАдрес, 'нет данных') AS Адрес
    |    ,СпрЮЛ.ЮрАдрес AS АдресЮЛ
    |    ,СпрФЛ.ЮрАдрес AS АдресФЛ
    |FROM _1SJOURN AS Журнал With (NOLOCK)
    |    INNER JOIN $Документ.ЗаявкаПокупателя AS ЗаявкаПокупателя With (NOLOCK) ON Журнал.IDDOC = ЗаявкаПокупателя.IDDOC
    |    INNER JOIN $ДокументСтроки.ЗаявкаПокупателя AS ЗаявкаПокупателяСтроки With (NOLOCK) ON ЗаявкаПокупателя.IDDOC = ЗаявкаПокупателяСтроки.IDDOC
    |    INNER JOIN $Справочник.Номенклатура AS Номенклатура With (NOLOCK) ON Номенклатура.ID = $ЗаявкаПокупателяСтроки.Номенклатура
    |    INNER JOIN $Справочник.Контрагенты AS Контрагенты With (NOLOCK) ON Контрагенты.ID = $ЗаявкаПокупателя.Контрагент
    |
    |    LEFT JOIN Справочник.ЮрЛица AS СпрЮЛ    ON Substr(Контрагенты.ЮрФизЛицо,1,4) = $ВидСправочника36.ЮрЛица    AND СпрЮЛ.ID = Substr(Контрагенты.ЮрФизЛицо,5,9)
    |    LEFT JOIN Справочник.ФизЛица AS СпрФЛ   ON Substr(Контрагенты.ЮрФизЛицо,1,4) = $ВидСправочника36.ФизЛица AND СпрФЛ.ID = substr(Контрагенты.ЮрФизЛицо,5,9)    
    |
    |WHERE $ЗаявкаПокупателя.ДатаОтгрузки >:НачДата AND $ЗаявкаПокупателя.ДатаОтгрузки <:КонДата
    |    AND Журнал.Closed & 1 = 1
    |";
1 mishaPH
 
22.01.24
18:57
не инн а адрес получить пардон. Хотя и ИНН также как я понял
2 Злопчинский
 
22.01.24
21:42
инн и адреса - и в юр лицах и в физлицах - одинаковый по структуре и по ссылке из Контрагентов (если штатно). прямым запростом тупо объединить две выборки с одинаковыми полями в одну таблицу и тянуть из нее ИНН и адреса
3 Злопчинский
 
22.01.24
21:45
одинаково
4 ADirks
 
23.01.24
07:10
(0) я бы порекомендовал почитать документацию по тому диалекту SQL, который используется. Например, в MS SQL действительно нет функций length и substr, зато есть len и substring.
5 АгентБезопасной Нацио
 
23.01.24
08:23
(2) объединять нельзя, иды у разных справочников неуникальны.
(0) база файловая или серверная?
6 ADirks
 
23.01.24
08:32
(5) чё-ж нелзя то, вполне можно
в индексы только не попадаем

select
    ЮФЛ.ИНН,
    ЮФЛ.ЮрАдрес

from
    ...
    left join (
        select
            ($ВидСправочника36.ЮрЛица + ID) ид13,
            ИНН,
            ЮрАдрес
        from
            $Справочник.ЮрЛица
        union all
        select
            ($ВидСправочника36.ФизЛица + ID) ID,
            ИНН,
            ЮрАдрес
        from
            $Справочник.ФизЛица
            
        ) ЮФЛ ON ЮФЛ.ид13 = $Контрагенты.ЮрФизЛицо
7 mishaPH
 
23.01.24
09:06
(5) скуль
8 mishaPH
 
23.01.24
09:07
(2) да дело не в этом. дело как в запрос корректно эту выборку поставить
9 mishaPH
 
23.01.24
09:09
(4) вот уже ближе. т.е. заменить и попробовать.
10 mishaPH
 
23.01.24
09:27
(4) большое спасибо
переписал запрос немного еще изменил и все выводит

    рс = СоздатьОбъект("ODBCRecordset");    
    ТекстЗапроса = "
    |SELECT ЗаявкаПокупателя.IDDOC [ЗаявкаПокупателя $Документ.ЗаявкаПокупателя]
    |    , Журнал.$ОбщийРеквизит.Автор [Автор $Справочник.Пользователи]
    |    , $ЗаявкаПокупателя.Контрагент [Кон $Справочник.Контрагенты]
    |    , $ЗаявкаПокупателя.ДатаОтгрузки Дата
    |    , $ЗаявкаПокупателяСтроки.Номенклатура [Ном $Справочник.Номенклатура]
    |    , $ЗаявкаПокупателяСтроки.Количество Количество
    |   , Номенклатура.Code КодНом
    |   , Контрагенты.Code КодКон
    |
    |    ,len($ВидСправочника36.ЮрЛица)
    |    ,CASE
    |        WHEN substring($Контрагенты.ЮрФизЛицо, 1, 4) = $ВидСправочника36.ЮрЛица THEN 'ЮрЛица'
    |        WHEN substring($Контрагенты.ЮрФизЛицо, 1, 4) = $ВидСправочника36.ФизЛица THEN 'ФизЛица'
    |        ELSE 'Не определен'
    |    END AS Вид
    |    ,COALESCE($СпрЮЛ.ЮрАдрес,$СпрФЛ.ЮрАдрес, 'нет данных') AS Адрес
    |    ,$СпрЮЛ.ЮрАдрес AS АдресЮЛ
    |    ,$СпрФЛ.ЮрАдрес AS АдресФЛ
    |FROM _1SJOURN AS Журнал With (NOLOCK)
    |    INNER JOIN $Документ.ЗаявкаПокупателя AS ЗаявкаПокупателя With (NOLOCK) ON Журнал.IDDOC = ЗаявкаПокупателя.IDDOC
    |    INNER JOIN $ДокументСтроки.ЗаявкаПокупателя AS ЗаявкаПокупателяСтроки With (NOLOCK) ON ЗаявкаПокупателя.IDDOC = ЗаявкаПокупателяСтроки.IDDOC
    |    INNER JOIN $Справочник.Номенклатура AS Номенклатура With (NOLOCK) ON Номенклатура.ID = $ЗаявкаПокупателяСтроки.Номенклатура
    |    INNER JOIN $Справочник.Контрагенты AS Контрагенты With (NOLOCK) ON Контрагенты.ID = $ЗаявкаПокупателя.Контрагент
    |
    |    LEFT JOIN $Справочник.ЮрЛица AS СпрЮЛ    ON substring($Контрагенты.ЮрФизЛицо,1,4) = $ВидСправочника36.ЮрЛица    AND СпрЮЛ.ID = substring($Контрагенты.ЮрФизЛицо,5,9)
    |    LEFT JOIN $Справочник.ФизЛица AS СпрФЛ   ON substring($Контрагенты.ЮрФизЛицо,1,4) = $ВидСправочника36.ФизЛица AND СпрФЛ.ID = substring($Контрагенты.ЮрФизЛицо,5,9)    
    |
    |WHERE $ЗаявкаПокупателя.ДатаОтгрузки >:НачДата AND $ЗаявкаПокупателя.ДатаОтгрузки <:КонДата
    |    AND Журнал.Closed & 1 = 1
    |";
11 mishaPH
 
23.01.24
09:34
А точнее даже так. убрав все лишнее.
ИНН тоже не проблема добавить

    рс = СоздатьОбъект("ODBCRecordset");    
    ТекстЗапроса = "
    |SELECT ЗаявкаПокупателя.IDDOC [ЗаявкаПокупателя $Документ.ЗаявкаПокупателя]
    |    , Журнал.$ОбщийРеквизит.Автор [Автор $Справочник.Пользователи]
    |    , $ЗаявкаПокупателя.Контрагент [Кон $Справочник.Контрагенты]
    |    , $ЗаявкаПокупателя.ДатаОтгрузки Дата
    |    , $ЗаявкаПокупателяСтроки.Номенклатура [Ном $Справочник.Номенклатура]
    |    , $ЗаявкаПокупателяСтроки.Количество Количество
    |   , Номенклатура.Code КодНом
    |   , Контрагенты.Code КодКон
    |
    |    ,COALESCE($СпрЮЛ.ЮрАдрес,$СпрФЛ.ЮрАдрес, 'нет данных') AS Адрес
    |FROM _1SJOURN AS Журнал With (NOLOCK)
    |    INNER JOIN $Документ.ЗаявкаПокупателя AS ЗаявкаПокупателя With (NOLOCK) ON Журнал.IDDOC = ЗаявкаПокупателя.IDDOC
    |    INNER JOIN $ДокументСтроки.ЗаявкаПокупателя AS ЗаявкаПокупателяСтроки With (NOLOCK) ON ЗаявкаПокупателя.IDDOC = ЗаявкаПокупателяСтроки.IDDOC
    |    INNER JOIN $Справочник.Номенклатура AS Номенклатура With (NOLOCK) ON Номенклатура.ID = $ЗаявкаПокупателяСтроки.Номенклатура
    |    INNER JOIN $Справочник.Контрагенты AS Контрагенты With (NOLOCK) ON Контрагенты.ID = $ЗаявкаПокупателя.Контрагент
    |
    |    LEFT JOIN $Справочник.ЮрЛица AS СпрЮЛ    ON substring($Контрагенты.ЮрФизЛицо,1,4) = $ВидСправочника36.ЮрЛица    AND СпрЮЛ.ID = substring($Контрагенты.ЮрФизЛицо,5,9)
    |    LEFT JOIN $Справочник.ФизЛица AS СпрФЛ   ON substring($Контрагенты.ЮрФизЛицо,1,4) = $ВидСправочника36.ФизЛица AND СпрФЛ.ID = substring($Контрагенты.ЮрФизЛицо,5,9)    
    |
    |WHERE $ЗаявкаПокупателя.ДатаОтгрузки >:НачДата AND $ЗаявкаПокупателя.ДатаОтгрузки <:КонДата
    |    AND Журнал.Closed & 1 = 1
    |";
12 АгентБезопасной Нацио
 
23.01.24
10:36
(6) по ид9 нельзя, по ид13 - конечно можно.
13 Злопчинский
 
24.01.24
08:26
(5) вытащить из одного справочника строку
получитьсписок контрагентов нужных (или всех) Контрагент.Физлица.ИНН и Конатрагент.Физлица.Адрес и аналогично для юрдица, объединить-то строки уже же можно вобщуютаблицу - будет select с полями инн и адрес...
?
14 Злопчинский
 
24.01.24
08:28
ну типа как в(6) оказывается
15 mishaPH
 
24.01.24
08:58
(14) Вот эта конструкция проста, и добавление получения адреса никак на быстродействии даже не сказалась

    рс = СоздатьОбъект("ODBCRecordset");    
    ТекстЗапроса = "
    |SELECT ЗаявкаПокупателя.IDDOC [ЗаявкаПокупателя $Документ.ЗаявкаПокупателя]
    |    , Журнал.$ОбщийРеквизит.Автор [Автор $Справочник.Пользователи]
    |    , $ЗаявкаПокупателя.Контрагент [Кон $Справочник.Контрагенты]
    |    , $ЗаявкаПокупателя.ДатаОтгрузки as [Дата $Дата]
    |    , Журнал.DATE_TIME_IDDOC as [ДатаДок $Дата]
    |    , $ЗаявкаПокупателя.СуммаВзаиморасчетов СуммаЗаявкиИтог
    |    , $ЗаявкаПокупателяСтроки.Номенклатура [Ном $Справочник.Номенклатура]
    |    , $ЗаявкаПокупателяСтроки.Количество Количество
    |   , RTRIM(Номенклатура.Code) КодНом
    |   , RTRIM(Контрагенты.Code) КодКон
    |    ,COALESCE($СпрЮЛ.ЮрАдрес,$СпрФЛ.ЮрАдрес, 'нет Адреса') AS ФактАдрес
    |
    |FROM _1SJOURN AS Журнал With (NOLOCK)
    |    INNER JOIN $Документ.ЗаявкаПокупателя AS ЗаявкаПокупателя With (NOLOCK) ON Журнал.IDDOC = ЗаявкаПокупателя.IDDOC
    |    INNER JOIN $ДокументСтроки.ЗаявкаПокупателя AS ЗаявкаПокупателяСтроки With (NOLOCK) ON ЗаявкаПокупателя.IDDOC = ЗаявкаПокупателяСтроки.IDDOC
    |    INNER JOIN $Справочник.Номенклатура AS Номенклатура With (NOLOCK) ON Номенклатура.ID = $ЗаявкаПокупателяСтроки.Номенклатура
    |    INNER JOIN $Справочник.Контрагенты AS Контрагенты With (NOLOCK) ON Контрагенты.ID = $ЗаявкаПокупателя.Контрагент
    |    LEFT JOIN $Справочник.ЮрЛица AS СпрЮЛ    ON substring($Контрагенты.ЮрФизЛицо,1,4) = $ВидСправочника36.ЮрЛица    AND СпрЮЛ.ID = substring($Контрагенты.ЮрФизЛицо,5,9)
    |    LEFT JOIN $Справочник.ФизЛица AS СпрФЛ   ON substring($Контрагенты.ЮрФизЛицо,1,4) = $ВидСправочника36.ФизЛица AND СпрФЛ.ID = substring($Контрагенты.ЮрФизЛицо,5,9)    
    |
    |WHERE $ЗаявкаПокупателя.ДатаОтгрузки >:НачДата AND $ЗаявкаПокупателя.ДатаОтгрузки <:КонДата
    |    AND Журнал.Closed & 1 = 1
    |";
16 mishaPH
 
24.01.24
09:00
а блин в юрфиз джойны With (NOLOCK) не добавил. Все время про это забываю.
17 АгентБезопасной Нацио
 
24.01.24
10:20
(16) "With" можно опускать...
18 trad
 
24.01.24
11:30
если сервер 2005+ и хинтов более одного, то без with будет ошибка
19 АгентБезопасной Нацио
 
24.01.24
12:10
(18) спасибо, не знал...
20 Djelf
 
24.01.24
15:07
Я не понимаю, зачем вы все время используете INNER JOIN в тех случаях когда мы точно знаем что правое соединение всегда есть (за исключением битых ссылок).
Я не спец по оптимизатору mssql, я спец по sqlite, но sqlite умеет перестраивать план запроса в таких случаях, mssql видимо тоже, т.е. иногда мы тянем всю таблицу правого джойна, а потом соединяем с некоторым штрафом.
Это не всегда критично, обычно работает, но иногда бывает ой,все.
Объясните: зачем тут INNER JOIN? Я не понимаю...
21 mishaPH
 
24.01.24
15:07
(20) вы о запросе? в  INNER JOIN только то, что 100% есть в доках.
22 Djelf
 
24.01.24
15:16
(21) Если у тебя в реквизитах документов нет таких реквизитов, то у тебя база разрушена. Иначе это не имеет смысла в подобном запросе.
 INNER JOIN $Справочник.Номенклатура AS Номенклатура With (NOLOCK) ON Номенклатура.ID = $ЗаявкаПокупателяСтроки.Номенклатура

Мы точно знаем что Номенклатура есть, зачем INNER JOIN? LEFT JOIN будет быстрее.
23 mishaPH
 
24.01.24
15:20
(22) не понял. что значит нет?
Да какая в принципе разница для этих ситуаций какой join
24 АгентБезопасной Нацио
 
24.01.24
16:21
(23) разница в том, что упрощенно говоря после соединения для внутреннего соединения сервер должен просканироваль результат и отбросить все кортежи с присоединенным нулл-ом. Т.е. сделать дополнительную работу, потратить время. Т.е. левое будет просто быстрее.
Но вообще, нужно смотреть на план запроса.
25 mishaPH
 
24.01.24
17:06
(24) попробую.
26 АгентБезопасной Нацио
 
24.01.24
17:19
(25) скорее всего, на твоих объемах ты увидишь ускорение только в плане запроса, а практически - не заметишь. Хотя - кто знает...
27 Djelf
 
24.01.24
17:24
(26) Копейка рубль бережет.
28 mishaPH
 
24.01.24
17:26
(26) (27) в выборке 230000 записей итого. попробовал. разницы нет вообще. по моему даже немного медленнее
29 Djelf
 
24.01.24
21:20
(28) На sql все уже зекешировано в памяти, +- по скорости выполнения выловить сложно, тем более что нынче процессоры сами разгоняются и замедляютсяются по собственному желанию.
На INNER JOIN против LEFT JOIN тратится не так чтобы невероятно больше ресурсов, но все равно тратится чуток больше. Можно не обращать внимания, а можно это учитывать при составлении запроса.
Я предпочитаю не давать оптимизатору лишних шалостей, если я уверен что левое соединение однозначно, то использую только левое соединение, как самое примитивное.
30 mishaPH
 
24.01.24
22:11
(29) согласен + когда массовая работа идет эти мелочи уже имеют значения
31 Злопчинский
 
25.01.24
00:01
Нескольо раз сталкивался, что для ТЗ конструкция ТЗ.ТекущаяКолонка() возвращает пустую строку, при этом колонка стопудово существует, и ошибка плавающая. Грешу что это так подкидывает ИТЗ, когда из ИТЗ выгружаются данные в ТЗ дл яотображения на форме (только не надо тут про поставщика данных, табличное поле итд ;-)
32 trad
 
25.01.24
06:21
(29) поддерживаю полностью
В подобных запросах, как выше, нужно использовать left join
33 mishaPH
 
25.01.24
07:40
(31) ИТЗ индексированная? классная вещь. Но натолкнулся на глюки. на больших массивах незаменима НО если много индексированных словил глюк, что система просто замирает после каких то операций пришлост обычную возвращать.
34 Злопчинский
 
25.01.24
08:24
(33) еще бы чтобы ИТЗ умела как-то напрямую результат черного запроса получать, ане через прокладку в виде обычной ТЗ
35 trad
 
25.01.24
08:30
(34) этого никогда не будет
36 mishaPH
 
25.01.24
08:45
(34) а нафига если это прямой успешно делает?
Я вот походу от черных вообще отказываюсь.

когда отчет делавшийся 4 часа делается 15 минут - это привлекает
37 mishaPH
 
25.01.24
08:46
запрос в (0) вообще не мой. Коллеге помог. У себя используем и покруче. Просто такого спр юрлиц нет вот и в тупик попал
38 vladmenleo
 
25.01.24
08:58
(34) ИТЗ и черный запрос. Забавная комбинация :) почему-бы на прямой переделать и никаких прокладок не надо
39 mishaPH
 
25.01.24
09:17
(38) да странно. если есть ИТЗ то значит 1с++ включен

Но видимо есть куча отчетом в и т.п. куча тз и запросов. Я вот если уже есть на прямой не переписываю но ИТЗ добавляю
40 vladmenleo
 
25.01.24
09:22
(39) Я наоборот, как встречаю какой-нибудь старый черный и приходит задание что-то исправить/доделать, так заодно на прямой переписываю
41 АгентБезопасной Нацио
 
25.01.24
09:32
(36) а если не секрет - что за _отчет_ делается 4 часа?
пы.сы. я черные так и не освоил (ну, в таком качестве, как Ёпрст, например).
42 mishaPH
 
25.01.24
09:35
(41) лучше не буду. наследие другого прога. сделано все что можно было сделать неоптимально.
43 Андрей_Андреич
 
naïve
25.01.24
09:40
(42) Меня больше 15 минут на прямых запросах смущает. Миллионы строк?
44 mishaPH
 
25.01.24
09:52
(43) не. запрос делается секунды.

там пришлось заменить на 4 запроса и далее логика раскручивается.
45 Андрей_Андреич
 
naïve
25.01.24
09:54
(44) Видать логика не самая логичная ... )))
46 АгентБезопасной Нацио
 
25.01.24
10:54
(44) но даже 14 минут постобработки данных - как-то смущают
47 mishaPH
 
03.02.24
17:26
Кстати коллеги. А не подскажите ли курсы по т-sql все таки как мне кажется всегда есть то, чего не знаешь. Чтобы понятно для чайника ну или тупого 1с ника.
48 Ёпрст
 
03.02.24
21:58
(47) Ицик Бен-Ган Основы T-SQL. Купи/скачай книжку. Более чем достаточно.