Получение данных из внешней базы 1С

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

Описанный способ не является единственно возможным для получения данных из базы 1С, но у него есть ряд преимуществ.: Впрочем, как и недостатков.

В общем, выдаю на-гора, и судите сами.

Автор: Андрей Вахрин

Источник : 1CSQL

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

Вьюшки создаются для таблиц справочников, журнала, шапок и табличных частей документов. Я использовал для этого, да и для создания таблиц и функций инструмент 1С++, потому как он распространяется бесплатно. А ставить его приходилось в фирмах, у которых не было столь мною любимого ToySQL. Хотя, используя именно библиотеку ToySQL, некоторые моменты можно значительно упростить.

Обработку запускаем на удаленной базе. Создадим для начала необходимые для работы объекты:

ЗагрузитьВнешнююКомпоненту("1CPP.dll");

МД = СоздатьОбъект("MetaDataWork");
СКЛ = СоздатьОбъект("ODBCRecordSet");

СКЛ.УстБД1С();
Теперь непосредственно сами вьюшки: Начнем с журнала документов.
Попытка
    СКЛ.Выполнить("DROP VIEW dbo.Журнал ");

Исключение
КонецПопытки;
стр = "CREATE VIEW dbo.Журнал
|AS
|SELECT DATE_TIME_IDDOC ДатаДок, IDDOC Ссылка, IDDOCDEF Вид, DOCNO Номер, Closed Проведен, ISMARK ПометкаУдаления
| ";
Для инд = 1 По Метаданные.ОбщийРеквизитДокумента() Цикл

    Если Метаданные.ОбщийРеквизитДокумента(инд).Сортировка = 1 Тогда
        стр = стр + ", sp"+ МД.ИДОбъекта(Метаданные.ОбщийРеквизитДокумента(инд)) + " "+

        Метаданные.ОбщийРеквизитДокумента(инд).Идентификатор;
    КонецЕсли;
КонецЦикла;

стр = стр + "
|FROM dbo._1SJOURN";
Попытка
    СКЛ.Выполнить(стр);

Исключение
    Сообщить("Не создан журнал документов...");
КонецПопытки;
Т.е. как мы видим, все реквизиты имеют теперь привычные для нас наименования и мы можем теперь обратиться к журналу документов следующим запросом: SELECT ДатаДок, Номер, Фирма, Контрагент FROM Журнал WHERE Проведен 0 Теперь перейдем к шапкам и табличным частям документов.
Для инд = 1 По Метаданные.Документ() Цикл

    Попытка
        СКЛ.Выполнить("DROP VIEW dbo.Док"+ Метаданные.Документ(инд).Идентификатор);

    Исключение
    КонецПопытки;
    стр = "CREATE VIEW dbo.Док"+ Метаданные.Документ(инд).Идентификатор + "
    |AS
    |SELECT IDDOC Ссылка, "+ МД.ИДОбъекта(Метаданные.Документ(инд)) + " Вид";

    Для рек = 1 По Метаданные.ОбщийРеквизитДокумента() Цикл

        Если Метаданные.ОбщийРеквизитДокумента(рек).Сортировка = 0 Тогда
            стр = стр + ", sp"+ МД.ИДОбъекта(Метаданные.ОбщийРеквизитДокумента(рек)) + " "+
            Метаданные.ОбщийРеквизитДокумента(рек).Идентификатор;

        КонецЕсли;
    КонецЦикла;
    Для рек = 1 По Метаданные.Документ(инд).РеквизитШапки() Цикл

        стр = стр + "
        |    , sp"+ МД.ИДОбъекта(Метаданные.Документ(инд).РеквизитШапки(рек)) + " "+

        Метаданные.Документ(инд).РеквизитШапки(рек).Идентификатор;
    КонецЦикла;

    стр = стр + "
    |FROM dbo.DH"+ МД.ИДОбъекта(Метаданные.Документ(инд));

    Попытка
        СКЛ.Выполнить(стр);
    Исключение
        Сообщить("Не созданы шапки документов... "+ Метаданные.Документ(инд).Идентификатор);

    КонецПопытки;

    Попытка
        СКЛ.Выполнить("DROP VIEW dbo.ТЧ"+ Метаданные.Документ(инд).Идентификатор);

    Исключение
    КонецПопытки;
    стр = "CREATE VIEW dbo.ТЧ"+ Метаданные.Документ(инд).Идентификатор + "
    |AS
    |SELECT IDDOC Ссылка, "+ МД.ИДОбъекта(Метаданные.Документ(инд)) + " Вид
    |, LINENO_ НомерСтроки";

    Для рек = 1 По Метаданные.Документ(инд).РеквизитТабличнойЧасти() Цикл

        стр = стр + "
        |    , sp"+ МД.ИДОбъекта(Метаданные.Документ(инд).РеквизитТабличнойЧасти(рек)) + " "+

         Метаданные.Документ(инд).РеквизитТабличнойЧасти(рек).Идентификатор;
    КонецЦикла;

    стр = стр + "
    |FROM dbo.DT"+ МД.ИДОбъекта(Метаданные.Документ(инд));

    Попытка
        СКЛ.Выполнить(стр);
    Исключение
        Сообщить("Не созданы табличные части документов... "+ Метаданные.Документ(инд).Идентификатор);

    КонецПопытки;
КонецЦикла;
Теперь мы можем смело расширить запрос по документам, вставив туда реквизиты шапок и табличных частей.

  SELECT Ж.ДатаДок
  , Ж.Номер
  , Ж.Фирма
  , Ж.Контрагент
  , Д.Валюта
  , Д.Курс
  , ТЧ.Номенклатура
  , ТЧ.Количество
  , ТЧ.Цена 
  FROM Журнал Ж
  , ДокПоступлениеТоваров Д
  , ТЧПоступлениеТоваров ТЧ
  WHERE Проведен  0
  AND Ж.Ссылка = Д.Ссылка
  AND Ж.Ссылка = ТЧ.Ссылка
Маловато данных, не правда ли? Но что мы получим в результате выполнения запроса в реквизитах, являющихся ссылками на элементы справочников? Правильно: мы получим всего лишь 36-тиричный внутренний ИД объекта. И ИД это будет принадлежать совсем не нашей базе и ничего хорошего мы из него не вытянем. Поэтому создаем вьюшки на справочники и смотрим как обходить данную проблему.
  Для инд = 1 По Метаданные.Справочник() Цикл

    Попытка
        СКЛ.Выполнить("DROP VIEW dbo.Спр"+ Метаданные.Справочник(инд).Идентификатор);

    Исключение
    КонецПопытки;
    стр = "CREATE VIEW dbo.Спр"+ Метаданные.Справочник(инд).Идентификатор + "
    |AS
    |SELECT ID Ссылка
    |, ISMARK ПометкаУдаления" +

    ?(Метаданные.Справочник(инд).ДлинаКода  0, ", CODE Код", "") +

    ?(Метаданные.Справочник(инд).ДлинаНаименования  0, ", DESCR Наименование", "") +

    ", " + МД.ИДОбъекта(Метаданные.Справочник(инд)) + " Вид";
    Если СокрЛП(Метаданные.Справочник(инд).Владелец)  "Метаданные" Тогда

        стр = стр + ", PARENTEXT Владелец";
    КонецЕсли;

    Если Метаданные.Справочник(инд).КоличествоУровней  1 Тогда
        стр = стр + ", PARENTID Родитель
        |, ISFOLDER ЭтоГруппа";

    КонецЕсли;

    Для рек = 1 По Метаданные.Справочник(инд).Реквизит() Цикл

        Если Метаданные.Справочник(инд).Реквизит(рек).Периодический = 1 Тогда

            Продолжить;
        КонецЕсли;
        стр = стр + "
        | , sp"+ МД.ИДОбъекта(Метаданные.Справочник(инд).Реквизит(рек)) + " "+

        Метаданные.Справочник(инд).Реквизит(рек).Идентификатор;
    КонецЦикла;

    стр = стр + "
    |FROM dbo.SC" + МД.ИДОбъекта(Метаданные.Справочник(инд));

    Попытка
        СКЛ.Выполнить(стр);
    Исключение
        Сообщить("Не созданы справочники... " + Метаданные.Справочник(инд).Идентификатор);

    КонецПопытки;
КонецЦикла;
И теперь смело меняем запрос:

  SELECT Ж.ДатаДок
  , Ж.Номер
  , СФ.Код Фирма
  , СК.Код Контрагент
  , СВ.Код Валюта
  , Д.Курс
  , СН.Код Номенклатура
  , ТЧ.Количество
  , ТЧ.Цена 
  FROM Журнал Ж
  , ДокПоступлениеТоваров Д
  , ТЧПоступлениеТоваров ТЧ
  , СпрФирмы СФ
  , СпрКонтрагенты СК
  , СпрВалюты СВ
  , СпрНоменклатура СН
  WHERE Проведен  0
  AND Ж.Ссылка = Д.Ссылка
  AND Ж.Ссылка = ТЧ.Ссылка
  AND СВ.Ссылка = Д.Валюта
  AND СН.Ссылка = ТЧ.Номенклатура
 

По крайней мере, мы теперь видим коды элементов справочников, участвующих в запросе и запросто можем найти соответствия в собственной базе (а далее еще и будет информация, как получить сразу ссылку на элемент!).

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

// периодические значения реквизитов справочников 
Попытка
    СКЛ.Выполнить("DROP VIEW dbo.Периодические");

Исключение
КонецПопытки;
стр = "";
Для инд = 1 По Метаданные.Справочник() Цикл

    тСпр = Метаданные.Справочник(инд);
    Для чРек = 1 По тСпр.Реквизит() Цикл

        тРек = тСпр.Реквизит(чРек);
        Если тРек.Периодический = 1 Тогда

            стр = стр + ?(СтрДлина(стр) = 0, "", "
            |UNION ALL
            |");

            стр = стр + 
            "select 'Спр"+ тСпр.Идентификатор + "' Справочник"+ ", '"+ тРек.Идентификатор + "
            |' Реквизит, S.ID Ссылка, C.DATE Дата, C.VALUE Значение
            |FROM SC"+ МД.ИДОбъекта(тСпр) + " S, _1SCONST C WHERE S.ID = C.OBJID";

        КонецЕсли;
    КонецЦикла;
КонецЦикла;
стр = "CREATE VIEW dbo.Периодические
|AS
|" + стр;

Попытка
    СКЛ.Выполнить(стр);
Исключение
    Сообщить("Не созданы периодические... ");

КонецПопытки;

// константы
Попытка
    СКЛ.Выполнить("DROP VIEW dbo.Константы");
Исключение

КонецПопытки;
стр = "CREATE VIEW dbo.Константы
|AS
|SELECT C1.ID ID
|        , C2.Идентификатор Идентификатор
|        , C2.Периодическая Периодическая
|        , C1.DATE Дата
|        , C1.VALUE Значение
|FROM _1SCONST C1, Конст C2
|WHERE C1.OBJID = '     0   '
|  AND C1.ID = C2.ID";
Попытка
    СКЛ.Выполнить(стр);

Исключение
    Сообщить("Не созданы константы... ");
КонецПопытки;

В последнем примере (создание вьюшек на константы), есть упоминание таблицы Конст - это служебная, вспомогательная таблица и формируется она следующим образом:

Попытка
    СКЛ.Выполнить("CREATE Table dbo.Конст
    |(ID Char(9), Идентификатор Char(60), Периодическая Int)");

Исключение
    Сообщить("Не создана таблица Конст");
КонецПопытки;
стр = "DELETE FROM Конст";

Попытка
    СКЛ.Выполнить(стр);
Исключение
КонецПопытки;
Для инд = 1 По Метаданные.Константа() Цикл

    тКонст = Метаданные.Константа(инд);
    Попытка
        СКЛ.Выполнить("INSERT INTO Конст (ID,Идентификатор,Периодическая)
        | VALUES ('"+ МД.ИДОбъекта(тКонст) + "','"+ тКонст.Идентификатор + "',"+ тКонст.Периодический + ")");

    Исключение
    КонецПопытки;
КонецЦикла;
Теперь разрешите привести пример получения периодического реквизита справочника на примере выбора курсов валют на указанную дату:

  SELECT Спр.Код
  , Пер.Значение Курс
  FROM СпрВалюты Спр 
  LEFT JOIN
  (SELECT Пер.Ссылка, Пер.Значение
  FROM Периодические Пер
  WHERE Пер.Реквизит = 'Курс' AND Пер.Дата =
  (SELECT Max(Дата) FROM Периодические WHERE Пер.Ссылка = Ссылка AND Дата  
Как видим, нелегкое это дело, каждый раз вставлять такой кусок кода в запрос. Но т.к. это все же удаленная база, то даже объект История из библиотеки ToySQL мы не можем использовать: Есть у меня также и код для создания вьюшек на таблицы регистров (только движения), с бухитогами не занимался, в связи с отсутствием таковой необходимости. Но, я так думаю, что на основании вышеприведенных примеров вам теперь и самим будет несложно это сделать. При работе с документами и справочниками возникают еще кое-какие проблемы. Вот те, с которыми мне пришлось столкнуться и решить: 1. В некоторых таблицах вид документа или справочника храниться в 10-тичном представлении, а в некоторых в 36-тиричном. Поэтому приходится использовать пару функций для преобразования одного в другое:

 стр = "create FUNCTION sp_tohex(@val int, @len1 int) RETURNS varchar(9)
  |AS
  |begin
  | declare @v int;
  | declare @tval varchar(9);
  | set @v = @val;
  | set @tval = '';
  |
  | while (@v > 0)
  | begin
  | set @tval = SUBSTRING('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ',1+@v%36,1)+@tval;
  | set @v = @v/36;
  | end;
  |
  | if @tval='' set @tval='0';
  |
  | while (len(@tval) Попытка
   СКЛ.Выполнить(стр);
Исключение
КонецПопытки;

 стр = "CREATE FUNCTION sp_toint(@val VarChar(9)) RETURNS int
  |AS
  |begin
  | declare @i int
  | declare @tval int
  | declare @v varchar(9)
  |
  | set @v = ltrim(rtrim(@val))
  | set @tval = 0
  | set @i = 0
  |
  | while @i Попытка
   СКЛ.Выполнить(стр);
Исключение
КонецПопытки;
2. Иногда надо получить время документа в удобоваримом виде (ЧЧ:ММ:СС):
  стр = "CREATE FUNCTION sp_gettime(@val VarChar(9)) RETURNS VarChar(8)
  |AS
  |begin
  | declare @i int
  | declare @h int
  | declare @m int
  | declare @s int
  |
  | set @i = dbo.sp_toint(@val)
  |
  | set @h = ((@i/10000) / 60) / 60
  | set @m = ((@i/10000) / 60) - @h * 60
  | set @s = (@i/10000) - (@h * 60 * 60 + @m * 60)
  |
  | RETURN( cast(@h as char(2)) + ':' + cast(@m as char(2)) + ':' + cast(@s as 
  char(2)) )
  |end";

Попытка
   СКЛ.Выполнить(стр);
Исключение
КонецПопытки;

3. Функции получения уровня для элемента справочника и его полного кода:

Для инд = 1 По Метаданные.Справочник() Цикл

    Если Метаданные.Справочник(инд).КоличествоУровней  1 Тогда
        стр = "CREATE FUNCTION dbo.Уровень" + Метаданные.Справочник(инд).Идентификатор + " (@ID_36 Char(9))
        |RETURNS INT AS
        |BEGIN
        | if @ID_36 IS NULL
        | return NULL
        |
        | declare @CurLevel INT
        | declare @ParID Char(9)
        | declare @CurID Char(9)
        |
        | set @CurLevel = 0
        | set @CurID = @ID_36
        | set @ParId = '000000000'
        |
        | while @ParId  ' 0 '
        | begin
        | select @ParId = ParentID From dbo.SC" + МД.ИДОбъекта(Метаданные.Справочник(инд)) + " Where ID = @CurID
        |
        | set @CurLevel = @CurLevel + 1
        | set @CurId = @ParID
        | end
        |
        | Return @CurLevel
        |END";

        Попытка
            СКЛ.Выполнить(стр);
        Исключение
            Сообщить("Не создана функция получения уровня для справочника: "+ Метаданные.Справочник(инд).Идентификатор);

        КонецПопытки;

        стр = "CREATE FUNCTION dbo.ПолныйКод" + Метаданные.Справочник(инд).Идентификатор + " (@ID_36 Char(9))
        |RETURNS CHAR(100) AS
        |BEGIN
        | if @ID_36 IS NULL
        | return NULL
        |
        | declare @FCode Char(100)
        | declare @CCode Char(24)
        | declare @ParID Char(9)
        | declare @CurID Char(9)
        |
        | set @FCode = ''
        | set @CurID = @ID_36
        | set @ParId = '000000000'
        |
        | while @ParId  ' 0 '
        | begin
        | select @ParId = ParentID, @CCode = Code From dbo.SC" + МД.ИДОбъекта(Метаданные.Справочник(инд)) + " Where ID = @CurID
        |
        | if @FCode = ''
        | set @FCode = ltrim(rtrim(@CCode))
        | else
        | set @FCode = ltrim(rtrim(@CCode)) + '/' + @FCode
        |
        | set @CurId = @ParID
        | end
        |
        | Return ltrim(rtrim(@FCode))
        |END";
        Попытка
            СКЛ.Выполнить(стр);

        Исключение
            Сообщить("Не создана функция получения полного кода: "+ Метаданные.Справочник(инд).Идентификатор);

        КонецПопытки;
    КонецЕсли;
КонецЦикла;
4. А еще нам очень было бы неплохо иметь под рукой таблицу с перечислениями, которой, как вы знаете, с базе просто нет. Ну а раз нет, то никто нам не мешает такую таблицу создать.

Попытка
    стр = "CREATE Table dbo.Перечисления
    |(Вид char(30),Значение char(30),ID char(9))";

    СКЛ.Выполнить(стр);
Исключение
КонецПопытки;
стр = "DELETE FROM Перечисления";

Попытка
    СКЛ.Выполнить(стр);
Исключение
КонецПопытки;
Для инд = 1 По Метаданные.Перечисление() Цикл

    пер = Перечисление.ПолучитьАтрибут(Метаданные.Перечисление(инд).Идентификатор);

    Для инд1 = 1 По пер.КоличествоЗначений() Цикл

        стр = "INSERT INTO Перечисления (Вид, Значение, ID) VALUES
        | ('"+ Метаданные.Перечисление(инд).Идентификатор + "',
        | '"+ пер.ЗначениеПоНомеру(инд1).Идентификатор() + "',
        | '"+ МД.ЗначениеВСтрокуБД(пер.ЗначениеПоНомеру(инд1)) + "')";

        Попытка
            СКЛ.Выполнить(стр);
        Исключение
            Сообщить("Не созданы перечисления...");

        КонецПопытки;
    КонецЦикла;
КонецЦикла;

Да, еще можно создать таблицу видов для документов и справочников, видов субконто и т.д и т.п. Но это вы уж самостоятельно. Единственное, что я вам дам, так это пример запроса из разработки. Этот запрос получает таблицу для переноса документов из Комплексной конфигурации в ТиС:

 
Select 
'ЗаявкаПокупателя' тВид, 
Left(Ж.ДатаДок, 8) ДатаДок, 
dbo.sp_gettime(substring(Ж.ДатаДок,9,6)) Время, 
Ж.Номер, 
Ф.Код Фирма, 
Ю.Код ЮрЛицо, 
СпрСчета.Код БанковскийСчет, 
К.Код Контрагент, 
СпрДог.Код Договор, 
СпрВал.Код Валюта, 
Д.Курс, Д.УчитыватьНДС, 
Д.СуммаВклНДС, 
Д.УчитыватьНП, 
Д.СуммаВклНП, 
Д.СуммаВзаиморасчетов, 
СпрТЦ.Код ТипЦен, 
СпрСк.Код 
Скидка, Д.ДатаОплаты, 
Д.ДатаОтгрузки, 
СпрСкл.Код Склад, 
ПерВО.Значение ВидОперации, 
ПерСР.Значение СпособРезервирования, 
СпрНом.Код Номенклатура, 
ТЧ.Количество, 
ТЧ.Коэффициент, 
ТЧ.Цена, 
ТЧ.Сумма, 
ПерНДС.Значение СтавкаНДС, 
ТЧ.СуммаНДС 
From 
Журнал Ж, 
ДокЗаявкаПокупателя Д, 
ТЧЗаявкаПокупателя ТЧ, 
СпрФирмы Ф, 
СпрСвоиЮрЛица Ю, 
СпрБанковскиеСчета СпрСчета, 
СпрКонтрагенты К, 
СпрДоговоры СпрДог, 
СпрВалюты СпрВал, 
СпрТипыЦен СпрТЦ, 
СпрСкидки СпрСк, 
СпрСклады СпрСкл, 
СпрНоменклатура СпрНом, 
Перечисления ПерВО, 
Перечисления ПерСР, 
Перечисления ПерНДС
where 
Ж.Ссылка = Д.Ссылка
and Ж.Ссылка = ТЧ.Ссылка 
and Ф.Ссылка = Ж.Фирма
and Ю.Ссылка = Ж.ЮрЛицо
and К.Ссылка = Д.Контрагент
and Д.Договор *= СпрДог.Ссылка
and Д.Валюта *= СпрВал.Ссылка
and Д.ТипЦен *= СпрТЦ.Ссылка 
and Д.Скидка *= СпрСк.Ссылка
and Д.Склад *= СпрСкл.Ссылка
and ТЧ.Номенклатура *= СпрНом.Ссылка and Д.БанковскийСчет *= СпрСчета.Ссылка and ТЧ.СтавкаНДС *= ПерНДС.ID 
and Д.ВидОперации *= ПерВО.ID and Д.СпособРезервирования *= ПерСР.ID 

Ну а на закуску - самое вкусное. Выполнив запрос, который расположен чуть выше по тексту, мы получим таблицу, по которой сможем найти все необходимые ссылки и создать документы в собственной базе. Но разве это было бы быстрее, чем большинство других способов переноса, где есть такая необходимость поиска ссылок? Нет, конечно же! Нам было бы интересно сразу получить эти самые ссылки на объекты собственной базы, потом только подставлять их и записывать вновь созданные или редактируемые документы. И такой способ есть! Решение, которое я приведу ниже, использует компоненту ToySQL.


  SELECT ExtQuery.ДатаДок 
  , ExtQuery.Время 
  , ExtQuery.Номер 
  , [Спр1.Ссылка] Фирма
  , [Спр2.Ссылка] ЮрЛицо
  , [Спр3.Ссылка] БанковскийСчет
  , [Спр4.Ссылка] Контрагент
  , ExtQuery.Договор 
  , [Спр5.Ссылка] Валюта
  , ExtQuery.Курс 
  , ExtQuery.УчитыватьНДС 
  , ExtQuery.СуммаВклНДС 
  , ExtQuery.СуммаВзаиморасчетов 
  , ExtQuery.ТипЦен 
  , ExtQuery.Скидка 
  , ExtQuery.ДатаОплаты 
  , ExtQuery.ДатаОтгрузки 
  , ExtQuery.Склад 
  , ExtQuery.ВидОперации 
  , ExtQuery.СпособРезервирования 
  , [Спр6.Ссылка] Номенклатура
  , ExtQuery.Количество 
  , ExtQuery.Коэффициент 
  , ExtQuery.Цена 
  , ExtQuery.Сумма 
  , ExtQuery.СтавкаНДС 
  , ExtQuery.СуммаНДС 
  FROM 
  (SELECT * FROM 
  OPENQUERY(K44, 'Select Left(Ж.ДатаДок, 8) ДатаДок,
  dbo.sp_gettime(substring(Ж.ДатаДок,9,6)) Время,
  Ж.Номер,
  Ф.Код Фирма, 
  Ю.Код ЮрЛицо, 
  СпрСчета.Код БанковскийСчет,
  К.Код Контрагент,
  СпрДог.Код Договор,
  СпрВал.Код Валюта,
  Д.Курс,
  Д.УчитыватьНДС,
  Д.СуммаВклНДС,
  Д.УчитыватьНП,
  Д.СуммаВклНП,
  Д.СуммаВзаиморасчетов,
  СпрТЦ.Код ТипЦен,
  СпрСк.Код Скидка,
  Д.ДатаОплаты,
  Д.ДатаОтгрузки,
  СпрСкл.Код Склад,
  ПерВО.Значение ВидОперации,
  ПерСР.Значение СпособРезервирования,
  СпрНом.Код Номенклатура,
  ТЧ.Количество,
  ТЧ.Коэффициент,
  ТЧ.Цена,
  ТЧ.Сумма,
  ПерНДС.Значение СтавкаНДС,
  ТЧ.СуммаНДС
  
  From Журнал Ж, 
  ДокЗаявкаПокупателя Д, 
  ТЧЗаявкаПокупателя ТЧ, 
  СпрФирмы Ф, 
  СпрСвоиЮрЛица Ю, 
  СпрБанковскиеСчета СпрСчета, 
  СпрКонтрагенты К, 
  СпрДоговоры СпрДог, 
  СпрВалюты СпрВал, 
  СпрТипыЦен СпрТЦ, 
  СпрСкидки СпрСк, 
  СпрСклады СпрСкл, 
  СпрНоменклатура СпрНом,
  Перечисления ПерВО,
  Перечисления ПерСР,
  Перечисления ПерНДС
  
  where Ж.Ссылка = Д.Ссылка
  and Ж.Ссылка = ТЧ.Ссылка
  and Ф.Ссылка = Ж.Фирма
  and Ю.Ссылка = Ж.ЮрЛицо
  and К.Ссылка = Д.Контрагент
  and Д.Договор *= СпрДог.Ссылка
  and Д.Валюта *= СпрВал.Ссылка
  and Д.ТипЦен *= СпрТЦ.Ссылка
  and Д.Скидка *= СпрСк.Ссылка
  and Д.Склад *= СпрСкл.Ссылка
  and ТЧ.Номенклатура *= СпрНом.Ссылка
  and Д.БанковскийСчет *= СпрСчета.Ссылка
  and ТЧ.СтавкаНДС *= ПерНДС.ID
  and Д.ВидОперации *= ПерВО.ID
  and Д.СпособРезервирования *= ПерСР.ID')) ExtQuery
  , [Справочник.Фирмы] Спр1
  , [Справочник.СвоиЮрЛица] Спр2
  , [Справочник.БанковскиеСчета] Спр3
  , [Справочник.Контрагенты] Спр4
  , [Справочник.Валюты] Спр5
  , [Справочник.Номенклатура] Спр6
  WHERE ExtQuery.Фирма*=[Спр1.Код]
  AND ExtQuery.ЮрЛицо*=[Спр2.Код]
  AND ExtQuery.БанковскийСчет*=[Спр3.Код]
  AND ExtQuery.Контрагент*=[Спр4.Код]
  AND ExtQuery.Валюта*=[Спр5.Код]
  AND ExtQuery.Номенклатура*=[Спр6.Код]
  

Как видим, большая часть запроса нам уже известна. Что же есть его ? Это решение построено на возможности обратиться к связанному серверу (см. sp_addlinkedserver). Хотя это может быть абсолютно любым образом полученный подзапрос. А вот уже связка с собственными объектами по каким-либо уникальным ключам (например, код для справочника) и получение готовых ссылок на объекты - это уже как раз то, что мы и хотели. Осталось только выполнить приведенный МетаЗапрос и Выгрузить результаты его выполнения в таблицу значений.

Вот собственно и все.

Оригинал статьи: http://1csql.ru/materials/articles/develop/017.htm
Опубликована: 8 ноября 2004

Начать дискуссию

Минцифры запретит массовые спам-звонки

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

Курсы повышения
квалификации

20
Официальное удостоверение с занесением в госреестр Рособрнадзора

Как зайти в реферальную программу «Клерка». Делюсь личным опытом

Если вы задумываетесь о том, как получить дополнительный доход, то этот пост для вас. Расскажу о реферальной программе «Клерка»: что это, как работает и почему такое сотрудничество приносит пользу. А еще на собственном примере покажу и расскажу, как зарабатывать на рекомендациях. Забирайте пошаговый алгоритм в закладки!

Как зайти в реферальную программу «Клерка». Делюсь личным опытом
2
Кадры

На рынке труда пенсионеры и студенты стали ценными кадрами

На фоне дефицита кадров компании заинтересовались в найме студентов и пенсионеров. Теперь им предлагают работу в 2 раза чаще.

Лучшие спикеры, новый каждый день

7 типичных ошибок, которые допускают в стритфуд

Стритфуд — динамично развивающийся сегмент рынка общепита, популярный как у начинающих предпринимателей, так и у опытных рестораторов. Однако и здесь есть свои подводные камни. Разберем 7 главных ошибок, которые допускают владельцы стритфуда, и расскажем, какие из них можно избежать с помощью системы автоматизации кафе Fusion POS.

7 типичных ошибок, которые допускают в стритфуд

Модульбанк повысил лимит переводов на карты физлиц для селлеров до 30 млн рублей

С 1 мая все физлица могут бесплатно переводить между своими счетами до 30 миллионов рублей в месяц через СБП. В Модульбанке повышенный лимит переводов для селлеров доступен уже сейчас с Маркет Картой.

Незавершенное строительство позволяет претендовать на выкуп земли много ниже кадастровой стоимости

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

Опытом делятся эксперты-практики, без воды

КУБ дня. Про штрафы за статотчетность

До текущего года Росстат штрафами только пугал, а теперь наказывает. Как отбиться от штрафа, есть ли шанс?

КУБ дня. Про штрафы за статотчетность

Как принимать оплату через СБП и работать по 54-ФЗ с наименьшими затратами

Согласно закону 54-ФЗ, в большинстве случаев при приеме платежей от физических лиц бизнесу — будь то предприниматель или юридическое лицо — нужна онлайн-касса. По-другому, каждый платеж нужно фискализировать. Расскажем, как сделать это с наименьшими затратами.

Как принимать оплату через СБП и работать по 54-ФЗ с наименьшими затратами
Бесплатно с НДФЛ

Поправки в НК–2024: что изменится в НДФЛ

Изменят расчет НДФЛ по процентам от вкладов. Минимальный срок владения для продажи квартир будут считать по-новому для перепланировки и покупки за маткапитал.

Поправки в НК–2024: что изменится в НДФЛ

На одну госпошлину стало меньше

С 23 апреля транспортные средства, переданные фронту, освободили от уплаты госпошлины при постановке на учет.

ЕСХН

Когда применяющих ЕСХН освободят от уплаты налога на имущество

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

Реклама

ФАС обвиняет Сбер в нарушении рекламного законодательства

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

Миникурсы, текстовые и видеоинструкции для бухгалтеров

Глава Минфина: в России нужна «донастройка» налогов

Антон Силуанов готов предложить бизнесу идеи по модернизации фискальной системы.

Брокерские компании восстановились после убытка в 2022 году

Известно, что брокеры получили 33,7 млрд рублей чистой прибыли за 2023 год и стали больше зарабатывать на услугах по размещению ценных бумаг.

Берешь и запускаешь: как Telega.in меняет правила игры в размещении рекламы в Телеграм для бизнеса

Телеграм уже давно не просто мессенджер — это полноценная арена для маркетологов, которые каждый день соревнуются за внимание аудитории. Платформа активно развивается, предлагая все новые и новые рекламные инструменты. Но с ростом возможностей возникает и потребность в автоматизации. Здесь на сцену выходит Telega.in, превращая сложные процессы в дело пяти минут.

Берешь и запускаешь: как Telega.in меняет правила игры в размещении рекламы в Телеграм для бизнеса

Бухгалтеры не знают элементарных вещей!

20 лет я главный бухгалтер. Большую часть из них работала в Хабаровском крае. С проблемой ниже, конечно, сталкивалась, но не сплошь, а вопрос с контрагентом решался быстро и безболезненно.

Бухгалтеры не знают элементарных вещей!

Еще один великолепный МИФ о техподдержке СБИС

Пишу в техподдержку СБИС так мол и так, почему Уведомление не доходит до ФНС?

Еще один великолепный МИФ о техподдержке СБИС

Обязательное применение МЧД СФР с 11 марта 2024 года: кто может отчитываться без доверенности, переходный период

СФР с 11 марта 2024 года начал принимать отчеты от страхователей в электронном виде с машиночитаемыми доверенностями — МЧД СФР. Теперь документы больше не получится сдать на сайте фонда с помощью скан-копий бумажных доверенностей. Разбираемся, что поменялось для страхователей и как сейчас представлять отчеты в СФР.

Обязательное применение МЧД СФР с 11 марта 2024 года: кто может отчитываться без доверенности, переходный период

Календарь вебинаров для бухгалтера в мае 2024. Платные и бесплатные

Собрали для вас анонсы вебинаров на май 2024 года.

Интересные материалы

Уменьшение патента на взносы, если у ИП несколько патентов

Не самая справедливая тема, а что делать. Вы знаете (я надеюсь) что патент можно уменьшать на фиксированные взносы ИП, а еще на взносы с зарплаты работников. И правила очень похожи на уменьшение упрощенки на взносы, но, как говорится, есть нюанс.

Уменьшение патента на взносы, если у ИП несколько патентов