Практикум по созданию обменов данными через протокол oData «за полдня»


Про oData и 1С было довольно много написано, однако же описания работы и с чтением, и с записью данных через JSON я так и не встретил ни на этом ресурсе ни на других. Попробую раскрыть эту тему.

Реализация REST-интерфейса от 1С – песня долгая, унылая, про борьбу нещадную и Пирровы победы… Но всё же применение ему есть, и в некоторых случаях он не просто производительнее и выгоднее в реализации других технологий обмена, но и просто незаменим.

При этом, до сих пор порядка 50% специалистов или вообще об oData не слышали или «что-то слышали», но «нужен обмен – COM forever», при том что более тормозной технологии обмена, по-моему, вообще на текущий момент не существует.

Описание теории в этой статье давать не буду, как и описание публикации базы данных на web-сервере, на все необходимые (и весьма интересные) для прочтения статьи ссылки приведу в конце статьи, сейчас займемся жёсткой практикой, и поймем, что «полдня» — это вполне реально)

Решение задач на получение данных (например получение остатков по банковским счетам) вообще делается «на лету», поэтому разберем случай с выгрузкой данных в приемник.

Итак, имеем две БД «управленческая» сильно переписаная КА 1.1 и самописная БД для учета контрагентов и банковских счетов «юрбаза», в которой работают юристы и финансовый отдел. Первичный ввод информации о контрагенте производится в юрбазе, нам же нужно оперативно выгрузить из нее информацию в управленческую. В данном случае весь код отрабатывается в юрбазе посредством GET и POST запросов в управленческую.

Оговорюсь, код не претендует на безукоризненность и соответствие стандартам, т.к. писалось «на скорую руку», надеюсь что сильно пинать за это меня не будут)

Для начала добавляем регистр сведений, скажем «Измененные объекты» для регистрации объектов при их записи, пишем процедуры регистрации, в модулях выгрузки будем обращаться к данным регистра. Ессно добавляем рег.задание для запуска выгрузки, оставляем за собой возможность интерактивной обработки данных из обработки. Для хранения данных для соединения с управленческой базой добавляем регистр сведений «Серверы oData». Описание действий дано, дабы код запросов был более читабелен.

Итак, код:

Процедура ВыполнитьВыгрузкуИзмененныхОбъектов(ИнтерактивныйРежим = Ложь) Экспорт

// если ничего нет не соединяемся
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| ИзмененныеОбъекты.Объект КАК Объект
|ИЗ
| РегистрСведений.ИзмененныеОбъекты КАК ИзмененныеОбъекты";

Если Запрос.Выполнить().Пустой() Тогда
Возврат;
КонецЕсли;

Если ИнтерактивныйРежим Тогда
ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'Старт обработки: %1'"), ТекущаяДатаСеанса());
СообщениеТрассировки(ТекстСообщения, ИнтерактивныйРежим);
КонецЕсли;

СтруктураПодключения = Новый Структура("Сервер,БазаДанных,Пользователь,Пароль");

Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| СерверыOData.Сервер КАК Сервер,
| СерверыOData.БазаДанных КАК БазаДанных,
| СерверыOData.Пользователь КАК Пользователь,
| СерверыOData.Пароль КАК Пароль
|ИЗ
| РегистрСведений.СерверыOData КАК СерверыOData
|ГДЕ
| СерверыOData.Идентификатор = ЗНАЧЕНИЕ(Перечисление.ИдентификаторыБазДанных.Управленческая)";

Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
ЗаполнитьЗначенияСвойств(СтруктураПодключения, Выборка);
Иначе
ТекстСообщения = НСтр("ru = 'Запись регистра сведений Серверы oData для управленческой БД не обнаружена.'");
СообщениеТрассировки(ТекстСообщения, ИнтерактивныйРежим, УровеньЖурналаРегистрации.Ошибка);
Возврат;
КонецЕсли;

ЗаголовокHTTP = Новый Соответствие();
ЗаголовокHTTP.Вставить("Accept", "application/json");

ЗаголовокHTTP2 = Новый Соответствие();
ЗаголовокHTTP2.Вставить("Content-Type", "application/json; charset=utf-8");

Попытка
Соединение = Новый HTTPСоединение(СтруктураПодключения.Сервер, , СтруктураПодключения.Пользователь, СтруктураПодключения.Пароль);
Исключение
ТекстСообщения = НСтр("ru = 'Ошибка соединения с WEB-сервером управленческой БД.'");
СообщениеТрассировки(ТекстСообщения, ИнтерактивныйРежим, УровеньЖурналаРегистрации.Ошибка);
Соединение = Неопределено;
Возврат;
КонецПопытки;

ПараметрыHTTP = Новый Структура("ИнтерактивныйРежим,Соединение,АдресРесурса,ТекстЗапроса,ЗаголовокHTTP,КодСостояния,Ответ,ТекущийОбъект,КритическаяОшибка,Метод",
ИнтерактивныйРежим, Соединение, "", "", ЗаголовокHTTP, 0, "", Неопределено, Ложь, Неопределено);

// Контрагенты

Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| ИзмененныеОбъекты.Объект КАК Объект,
| ИзмененныеОбъекты.Объект.Наименование КАК Description,
| ИзмененныеОбъекты.Объект.Наименование КАК НаименованиеПолное,
| ИзмененныеОбъекты.Объект.ИНН КАК ИНН,
| ИзмененныеОбъекты.Объект.КПП КАК КПП,
| ИзмененныеОбъекты.Объект.ОГРН КАК ОГРН,
| ВЫБОР
|  КОГДА ИзмененныеОбъекты.Объект.ФормаСобственности.Сокращение = ""ИП""
|   ТОГДА ""ФизЛицо""
|  ИНАЧЕ ""ЮрЛицо""
| КОНЕЦ КАК ЮрФизЛицо,
| ВЫБОР
|  КОГДА ИзмененныеОбъекты.Объект.СистемаНалогообложения = ЗНАЧЕНИЕ(Справочник.СистемаНалогообложения.УСН)
|   ТОГДА ""Упрощенная""
|  ИНАЧЕ ""Общая""
| КОНЕЦ КАК СистемаНалогообложения
|ИЗ
| РегистрСведений.ИзмененныеОбъекты КАК ИзмененныеОбъекты
|ГДЕ
| ИзмененныеОбъекты.Объект ССЫЛКА Справочник.Контрагенты";

Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл

// Сначала поищем контрагента в базе-приемнике для определения типа запроса POST или PATCH
// По правильному хорошо бы хранить GUID существующих в другой базе объектов и искать по нему, но...
ПараметрыHTTP.ТекущийОбъект = Выборка.Объект;
ПараметрыHTTP.АдресРесурса = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = '%1/odata/standard.odata/Catalog_Контрагенты?$select=Ref_Key&$filter=ИНН eq %2%3%2 and КПП eq %2%4%2'"),
СтруктураПодключения.БазаДанных, "'", Выборка.ИНН, Выборка.КПП);

СоздатьЗапрос(ПараметрыHTTP); // Оптимизируем код
Если ПараметрыHTTP.КритическаяОшибка Тогда
Возврат;
ИначеЕсли ПараметрыHTTP.КодСостояния > 299 Тогда
Продолжить;
КонецЕсли;

ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(ПараметрыHTTP.Ответ);
СоответствиеJSON = ПрочитатьJSON(ЧтениеJSON, Истина);
МассивРеквизитов = СоответствиеJSON["value"]; // GET возвращает нам соответствие с массивом внутри

СоответствиеРеквизитов = Новый Соответствие;
СоответствиеРеквизитов.Вставить("odata.metadata", СоответствиеJSON["metadata"] + "/@Element");
СтруктураНаименований = Новый Структура("Description,ИНН,КПП,ОГРН,НаименованиеПолное", );

// Иногда в базе-источнике некорректно определена форма собственности контрагента, правят уже в управленческой, хаос)
Если НЕ МассивРеквизитов.Количество() = 0 Тогда
НовыйОбъект = Ложь;
Ref_Key = МассивРеквизитов[0]["Ref_Key"];
Иначе
НовыйОбъект = Истина;
СоответствиеРеквизитов.Вставить("ЮрФизЛицо", Выборка.ЮрФизЛицо);
КонецЕсли;

Для каждого КлючИЗначение Из СтруктураНаименований Цикл
СоответствиеРеквизитов.Вставить(КлючИЗначение.Ключ, Выборка[КлючИЗначение.Ключ]);
КонецЦикла;

ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, СоответствиеРеквизитов,,,,);
ПараметрыHTTP.ТекстЗапроса = ЗаписьJSON.Закрыть();

Если НовыйОбъект Тогда
ПараметрыHTTP.АдресРесурса = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = '%1/odata/standard.odata/Catalog_Контрагенты'"),
СтруктураПодключения.БазаДанных);
ПараметрыHTTP.Метод = "POST";
Иначе
ПараметрыHTTP.АдресРесурса = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = '%1/odata/standard.odata/Catalog_Контрагенты(guid%2%3%2)'"),
СтруктураПодключения.БазаДанных, "'", Ref_Key);
ПараметрыHTTP.Метод = "PATCH";
КонецЕсли;

СоздатьЗапрос(ПараметрыHTTP);
ПараметрыHTTP.Метод = Неопределено;
Если ПараметрыHTTP.КритическаяОшибка Тогда
Возврат;
ИначеЕсли ПараметрыHTTP.КодСостояния > 299 Тогда
Продолжить;
ИначеЕсли ПараметрыHTTP.КодСостояния = 200 ИЛИ ПараметрыHTTP.КодСостояния = 201 Тогда

// Если был POST нужно сбросить флаг отражения в регламентированном учете, есть у нас такой
// Суть в том, что мы не можем управлять процедурами ПередЗаписью и ПриЗаписи в приемнике,
// указание флага 1C_OData_DataLoadMode = true (ОбменДанными.Загрузка) в заголовке запроса результата не дает
Если НовыйОбъект Тогда

ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(ПараметрыHTTP.Ответ);
СоответствиеJSON = ПрочитатьJSON(ЧтениеJSON, Истина);
Ref_Key = СоответствиеJSON["Ref_Key"];

СоответствиеРеквизитов = Новый Соответствие;
СоответствиеРеквизитов.Вставить("odata.metadata", СоответствиеJSON["metadata"]);
СоответствиеРеквизитов.Вставить("ОтражатьВРегламентированномУчете", Ложь);

ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, СоответствиеРеквизитов,,,,);
ПараметрыHTTP.ТекстЗапроса = ЗаписьJSON.Закрыть();

ПараметрыHTTP.АдресРесурса = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = '%1/odata/standard.odata/Catalog_Контрагенты(guid%2%3%2)'"),
СтруктураПодключения.БазаДанных, "'", Ref_Key);
ПараметрыHTTP.Метод = "PATCH";

СоздатьЗапрос(ПараметрыHTTP);
ПараметрыHTTP.Метод = Неопределено;
Если ПараметрыHTTP.КритическаяОшибка Тогда
Возврат;
ИначеЕсли ПараметрыHTTP.КодСостояния > 299 Тогда
Продолжить;
КонецЕсли;

КонецЕсли;

НаборДанных = РегистрыСведений.ИзмененныеОбъекты.СоздатьНаборЗаписей();
НаборДанных.Отбор.Объект.Установить(Выборка.Объект);
НаборДанных.Записать(Истина);

КонецЕсли;

КонецЦикла;

// Ищем валюту рубли в приемнике. Если не найдена - продолжать смысла нет, т.к. б/с не запишется.
ПараметрыHTTP.АдресРесурса = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = '%1/odata/standard.odata/Catalog_Валюты?$select=Ref_Key&$filter=Code eq %2643%2'"),
СтруктураПодключения.БазаДанных, "'");

СоздатьЗапрос(ПараметрыHTTP);
Если ПараметрыHTTP.КритическаяОшибка ИЛИ ПараметрыHTTP.КодСостояния > 299 Тогда
Возврат;
КонецЕсли;

ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(ПараметрыHTTP.Ответ);
СоответствиеJSON = ПрочитатьJSON(ЧтениеJSON, Истина);
МассивРеквизитов = СоответствиеJSON["value"];

Если НЕ МассивРеквизитов.Количество() = 0 Тогда
ВалютаРубли = МассивРеквизитов[0]["Ref_Key"];
Иначе
ТекстСообщения = НСтр("ru = 'В базе-приемнике не найдена валюта с кодом 643. Выгрузка банковских счетов невозможна'");
СообщениеТрассировки(ТекстСообщения, ИнтерактивныйРежим, УровеньЖурналаРегистрации.Ошибка);
Соединение = Неопределено;
Возврат;
КонецЕсли;

// Банки и контрагенты для банковских счетов

Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| ИзмененныеОбъекты.Объект.Владелец КАК Объект,
| ИзмененныеОбъекты.Объект.Владелец.ИНН КАК ИНН,
| ИзмененныеОбъекты.Объект.Владелец.КПП КАК КПП,
| ВЫРАЗИТЬ("""" КАК СТРОКА(36)) КАК Ref_Key
|ИЗ
| РегистрСведений.ИзмененныеОбъекты КАК ИзмененныеОбъекты
|ГДЕ
| ИзмененныеОбъекты.Объект ССЫЛКА Справочник.БанковскиеСчета";

ТаблицаКонтрагенты = Запрос.Выполнить().Выгрузить();

Для каждого СтрокаТаблицы Из ТаблицаКонтрагенты Цикл

// Контрагентов только ищем, если все корректно они уже должны быть в приемнике
ПараметрыHTTP.ТекущийОбъект = СтрокаТаблицы.Объект;
ПараметрыHTTP.АдресРесурса = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = '%1/odata/standard.odata/Catalog_Контрагенты?$select=Ref_Key&$filter=ИНН eq %2%3%2 and КПП eq %2%4%2'"),
СтруктураПодключения.БазаДанных, "'", СтрокаТаблицы.ИНН, СтрокаТаблицы.КПП);

СоздатьЗапрос(ПараметрыHTTP);
Если ПараметрыHTTP.КритическаяОшибка Тогда
Возврат;
ИначеЕсли ПараметрыHTTP.КодСостояния > 299 Тогда
Продолжить;
КонецЕсли;

ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(ПараметрыHTTP.Ответ);
СоответствиеJSON = ПрочитатьJSON(ЧтениеJSON, Истина);
МассивРеквизитов = СоответствиеJSON["value"];

Если НЕ МассивРеквизитов.Количество() = 0 Тогда
СтрокаТаблицы.Ref_Key = МассивРеквизитов[0]["Ref_Key"];
КонецЕсли;

КонецЦикла;

Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| ИзмененныеОбъекты.Объект.Банк.Ссылка КАК Объект,
| ИзмененныеОбъекты.Объект.Банк.БИК КАК Code,
| ИзмененныеОбъекты.Объект.Банк.Наименование КАК Description,
| ИзмененныеОбъекты.Объект.Банк.КоррСчет КАК КоррСчет,
| ИзмененныеОбъекты.Объект.Банк.Адрес КАК Адрес,
| ИзмененныеОбъекты.Объект.Банк.Телефоны КАК Телефоны,
| ВЫРАЗИТЬ("""" КАК СТРОКА(36)) КАК Ref_Key
|ИЗ
| РегистрСведений.ИзмененныеОбъекты КАК ИзмененныеОбъекты
|ГДЕ
| ИзмененныеОбъекты.Объект ССЫЛКА Справочник.БанковскиеСчета";

ТаблицаБанки = Запрос.Выполнить().Выгрузить();

Для каждого СтрокаТаблицы Из ТаблицаБанки Цикл

// Банки ищем и создаем отсутствующие
ПараметрыHTTP.ТекущийОбъект = СтрокаТаблицы.Объект;
ПараметрыHTTP.АдресРесурса = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = '%1/odata/standard.odata/Catalog_Банки?$select=Ref_Key&$filter=Code eq %2%3%2'"),
СтруктураПодключения.БазаДанных, "'", СтрокаТаблицы.Code);

СоздатьЗапрос(ПараметрыHTTP);
Если ПараметрыHTTP.КритическаяОшибка Тогда
Возврат;
ИначеЕсли ПараметрыHTTP.КодСостояния > 299 Тогда
Продолжить;
КонецЕсли;

ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(ПараметрыHTTP.Ответ);
СоответствиеJSON = ПрочитатьJSON(ЧтениеJSON, Истина);
МассивРеквизитов = СоответствиеJSON["value"];

// Существующий банк не обновляем, это нужно делать регламентной процедурой Загрузка классификатора
Если НЕ МассивРеквизитов.Количество() = 0 Тогда
СтрокаТаблицы.Ref_Key = МассивРеквизитов[0]["Ref_Key"];
Продолжить;
КонецЕсли;

СоответствиеРеквизитов = Новый Соответствие;
СоответствиеРеквизитов.Вставить("odata.metadata", СоответствиеJSON["metadata"] + "/@Element");
СтруктураНаименований = Новый Структура("Code,Description,КоррСчет,Адрес,Телефоны", );

Для каждого КлючИЗначение Из СтруктураНаименований Цикл
СоответствиеРеквизитов.Вставить(КлючИЗначение.Ключ, СтрокаТаблицы[КлючИЗначение.Ключ]);
КонецЦикла;

ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, СоответствиеРеквизитов,,,,);
ПараметрыHTTP.ТекстЗапроса = ЗаписьJSON.Закрыть();

ПараметрыHTTP.АдресРесурса = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = '%1/odata/standard.odata/Catalog_Банки'"),
СтруктураПодключения.БазаДанных);
ПараметрыHTTP.Метод = "POST";

СоздатьЗапрос(ПараметрыHTTP);
ПараметрыHTTP.Метод = Неопределено;
Если ПараметрыHTTP.КритическаяОшибка Тогда
Возврат;
ИначеЕсли ПараметрыHTTP.КодСостояния > 299 Тогда
Продолжить;
ИначеЕсли ПараметрыHTTP.КодСостояния = 200 ИЛИ ПараметрыHTTP.КодСостояния = 201 Тогда
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(ПараметрыHTTP.Ответ);
СоответствиеJSON = ПрочитатьJSON(ЧтениеJSON, Истина);
СтрокаТаблицы.Ref_Key = СоответствиеJSON["Ref_Key"];
КонецЕсли;

КонецЦикла;

// БанковскиеСчета

Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ТаблицаБанки.Объект КАК Банк,
| ТаблицаБанки.Ref_Key КАК Ref_Key
|ПОМЕСТИТЬ Банки
|ИЗ
| &ТаблицаБанки КАК ТаблицаБанки
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ТаблицаКонтрагенты.Объект КАК Контрагент,
| ТаблицаКонтрагенты.Ref_Key КАК Ref_Key
|ПОМЕСТИТЬ Контрагенты
|ИЗ
| &ТаблицаКонтрагенты КАК ТаблицаКонтрагенты
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ РАЗЛИЧНЫЕ
| ИзмененныеОбъекты.Объект КАК Объект,
| ""StandardODATA.Catalog_Контрагенты"" КАК Owner_Type,
| Контрагенты.Ref_Key КАК Owner,
| ИзмененныеОбъекты.Объект.НомерСчета + "", "" + ИзмененныеОбъекты.Объект.Банк.Наименование КАК Description,
| ИзмененныеОбъекты.Объект.НомерСчета КАК НомерСчета,
| Банки.Ref_Key КАК Банк_Key,
| ""Расчетный"" КАК ВидСчета,
| ИзмененныеОбъекты.Объект.ДатаОткрытия КАК ДатаОткрытия,
| ИзмененныеОбъекты.Объект.ДатаЗакрытия КАК ДатаЗакрытия,
| &ВалютаРубли КАК ВалютаДенежныхСредств,
| ВЫБОР
|  КОГДА ИзмененныеОбъекты.Объект.СтатусСчета = ЗНАЧЕНИЕ(Справочник.СтатусыРасчетныхСчетов.Закрыт)
|    ИЛИ ИзмененныеОбъекты.Объект.СтатусСчета = ЗНАЧЕНИЕ(Справочник.СтатусыРасчетныхСчетов.Блок)
|   ТОГДА ИСТИНА
|  ИНАЧЕ ЛОЖЬ
| КОНЕЦ КАК ВременноНеиспользуется
|ИЗ
| РегистрСведений.ИзмененныеОбъекты КАК ИзмененныеОбъекты
|  ВНУТРЕННЕЕ СОЕДИНЕНИЕ Контрагенты КАК Контрагенты
|  ПО ИзмененныеОбъекты.Объект.Владелец = Контрагенты.Контрагент
|  ВНУТРЕННЕЕ СОЕДИНЕНИЕ Банки КАК Банки
|  ПО ИзмененныеОбъекты.Объект.Банк = Банки.Банк
|ГДЕ
| ИзмененныеОбъекты.Объект ССЫЛКА Справочник.БанковскиеСчета
| И НЕ Банки.Ref_Key = """"
| И НЕ Контрагенты.Ref_Key = """"";

Запрос.УстановитьПараметр("ТаблицаБанки", ТаблицаБанки);
Запрос.УстановитьПараметр("ТаблицаКонтрагенты", ТаблицаКонтрагенты);
Запрос.УстановитьПараметр("ВалютаРубли", ВалютаРубли);

Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл

ПараметрыHTTP.ТекущийОбъект = Выборка.Объект;
ПараметрыHTTP.АдресРесурса = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = '%1/odata/standard.odata/Catalog_БанковскиеСчета?$select=Ref_Key,Owner&$filter=НомерСчета eq %2%3%2'"), //  с isof и cast совместно в 8.3.10 не работает
СтруктураПодключения.БазаДанных, "'", Выборка.НомерСчета);

СоздатьЗапрос(ПараметрыHTTP);
Если ПараметрыHTTP.КритическаяОшибка Тогда
Возврат;
ИначеЕсли ПараметрыHTTP.КодСостояния > 299 Тогда
Продолжить;
КонецЕсли;

ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(ПараметрыHTTP.Ответ);
СоответствиеJSON = ПрочитатьJSON(ЧтениеJSON, Истина);
МассивРеквизитов = СоответствиеJSON["value"];

СоответствиеРеквизитов = Новый Соответствие;
СоответствиеРеквизитов.Вставить("odata.metadata", СоответствиеJSON["metadata"] + "/@Element");
СтруктураНаименований = Новый Структура("Description,Банк_Key,ДатаОткрытия,ДатаЗакрытия,ВременноНеиспользуется", );

НовыйОбъект = Истина;
Если НЕ МассивРеквизитов.Количество() = 0 Тогда
Для каждого Элемент Из МассивРеквизитов Цикл
Если Элемент["Owner"] = Выборка.Owner Тогда
НовыйОбъект = Ложь;
Ref_Key = Элемент["Ref_Key"];
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;

Если НовыйОбъект Тогда
СоответствиеРеквизитов.Вставить("Owner_Type", Выборка.Owner_Type);
СоответствиеРеквизитов.Вставить("Owner", Выборка.Owner);
СоответствиеРеквизитов.Вставить("НомерСчета", Выборка.НомерСчета);
СоответствиеРеквизитов.Вставить("ВидСчета", Выборка.ВидСчета);
СоответствиеРеквизитов.Вставить("ВалютаДенежныхСредств_Key", Выборка.ВалютаДенежныхСредств);
КонецЕсли;

Для каждого КлючИЗначение Из СтруктураНаименований Цикл
СоответствиеРеквизитов.Вставить(КлючИЗначение.Ключ, Выборка[КлючИЗначение.Ключ]);
КонецЦикла;

ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, СоответствиеРеквизитов,,,,);
ПараметрыHTTP.ТекстЗапроса = ЗаписьJSON.Закрыть();

Если НовыйОбъект Тогда
ПараметрыHTTP.АдресРесурса = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = '%1/odata/standard.odata/Catalog_БанковскиеСчета'"),
СтруктураПодключения.БазаДанных);
ПараметрыHTTP.Метод = "POST";
Иначе
ПараметрыHTTP.АдресРесурса = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = '%1/odata/standard.odata/Catalog_БанковскиеСчета(guid%2%3%2)'"),
СтруктураПодключения.БазаДанных, "'", Ref_Key);
ПараметрыHTTP.Метод = "PATCH";
КонецЕсли;

СоздатьЗапрос(ПараметрыHTTP);
ПараметрыHTTP.Метод = Неопределено;
Если ПараметрыHTTP.КритическаяОшибка Тогда
Возврат;
ИначеЕсли ПараметрыHTTP.КодСостояния > 299 Тогда
Продолжить;
ИначеЕсли ПараметрыHTTP.КодСостояния = 200 ИЛИ ПараметрыHTTP.КодСостояния = 201 Тогда
НаборДанных = РегистрыСведений.ИзмененныеОбъекты.СоздатьНаборЗаписей();
НаборДанных.Отбор.Объект.Установить(Выборка.Объект);
НаборДанных.Записать(Истина);
КонецЕсли;

КонецЦикла;

Соединение = Неопределено;

Если ИнтерактивныйРежим Тогда
ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'Завершение обработки: %1'"), ТекущаяДатаСеанса());
СообщениеТрассировки(ТекстСообщения, ИнтерактивныйРежим);
КонецЕсли;

КонецПроцедуры

Код процедуры создания HTTP-запроса:

Процедура СоздатьЗапрос(ПараметрыHTTP)

Попытка
Запрос = Новый HTTPЗапрос(ПараметрыHTTP.АдресРесурса, ПараметрыHTTP.ЗаголовокHTTP);
Если ПараметрыHTTP.Метод = Неопределено Тогда
ОтветОтСоединения = ПараметрыHTTP.Соединение.Получить(Запрос);
Иначе
Запрос.УстановитьТелоИзСтроки(ПараметрыHTTP.ТекстЗапроса);
ОтветОтСоединения = ПараметрыHTTP.Соединение.ВызватьHTTPМетод(ПараметрыHTTP.Метод, Запрос);
КонецЕсли;
ПараметрыHTTP.КодСостояния = ОтветОтСоединения.КодСостояния;
ПараметрыHTTP.Ответ = СтрЗаменить(ОтветОтСоединения.ПолучитьТелоКакСтроку("UTF-8"), "odata.", "");
Исключение
ТекстСообщения = НСтр("ru = 'Ошибка соединения с WEB-сервером управленческой БД.'");
СообщениеТрассировки(ТекстСообщения, ПараметрыHTTP.ИнтерактивныйРежим, УровеньЖурналаРегистрации.Ошибка);
ПараметрыHTTP.Соединение = Неопределено;
ПараметрыHTTP.КритическаяОшибка = Истина;
Возврат;
КонецПопытки;

Если ПараметрыHTTP.КодСостояния > 299 Тогда
ОбработатьОшибку(ПараметрыHTTP.Ответ, ПараметрыHTTP.КодСостояния, ПараметрыHTTP.ИнтерактивныйРежим, ПараметрыHTTP.ТекущийОбъект);
КонецЕсли;

КонецПроцедуры

Процедуры трассировки и обработки ошибок:

Функция ОписаниеВнутреннегоКодаОшибкиOData(КодОшибки)

Описание = Новый Структура();
Описание.Вставить("Код0", "Возможность не поддерживается");
Описание.Вставить("Код1", "Не удалось разобрать строку");
Описание.Вставить("Код2", "Неверный формат запроса");
Описание.Вставить("Код3", "Запрошенный тип представления не поддерживается");
Описание.Вставить("Код4", "Неверное значение свойства");
Описание.Вставить("Код5", "Остсутствует обязательное значение свойства");
Описание.Вставить("Код6", "Неверный URL");
Описание.Вставить("Код7", "Не хватает элемента ключа сущности");
Описание.Вставить("Код8", "Тип сущности не найден");
Описание.Вставить("Код9", "Экземпляр сущности не найден");
Описание.Вставить("Код10","Запрошенное свойство не найдено");
Описание.Вставить("Код11","Метод не найден");
Описание.Вставить("Код12","Отсутствует обязательный аргумент метода");
Описание.Вставить("Код13","Создание строк табличных частей напрямую не поддерживается");
Описание.Вставить("Код14","Ошибка разбора опций запроса");
Описание.Вставить("Код15","Сущность с таким ключом уже существует");
Описание.Вставить("Код16","Не удалось присвоить свойство");
Описание.Вставить("Код17","Объект не поддерживает режим загрузки данных");
Описание.Вставить("Код18","Ошибка инициализации интерфейса OData: в объекте есть свойства с однаковыми именами");
Описание.Вставить("Код19","Использованный HTTP-запрос запрещен в данном контексте");
Описание.Вставить("Код20","Ошибка прав доступа");
Описание.Вставить("Код21","Вызов нереализованной функции");
Описание.Вставить("Код101","Недопустимое значение аргумента функции");

Возврат ?(Описание.Свойство(КодОшибки),Описание[КодОшибки],"Неизвестная ошибка");

КонецФункции

Процедура ОбработатьОшибку(Ответ, КодСостояния, ИнтерактивныйРежим, ТекущийОбъект = Неопределено)

Если Найти(Ответ, "<!DOCTYPE html") = 0 И Найти(Ответ, "<m:error xmlns") = 0 Тогда // json

ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(Ответ);
СтруктураОтвета = ПрочитатьJSON(ЧтениеJSON);

КодОшибки = СтрЗаменить(СтруктураОтвета.error.code, "-1", "101");
ОписаниеОшибки = ОписаниеВнутреннегоКодаОшибкиOData("Код"+КодОшибки);
ЗначениеОшибки = СтруктураОтвета.error.message.value;

ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'Ошибка запроса. Описание ошибки: %1 - %2 Значение ошибки: %3'"),
СтрЗаменить(КодОшибки, "101", "-1"), ОписаниеОшибки, ЗначениеОшибки);

Иначе

ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'Ошибка сервера. Код ошибки: %1'"), КодСостояния);

КонецЕсли;

Если НЕ ТекущийОбъект = Неопределено Тогда
ТекстСообщения = ТекстСообщения + Символы.ПС + СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'Текущий объект: %1 Тип: %2'"), ТекущийОбъект, ТипЗнч(ТекущийОбъект));
КонецЕсли;

СообщениеТрассировки(ТекстСообщения, ИнтерактивныйРежим, УровеньЖурналаРегистрации.Ошибка);

КонецПроцедуры

Процедура СообщениеТрассировки(ТекстСообщения, ИнтерактивныйРежим, УровеньЖР = Неопределено)

Если ИнтерактивныйРежим Тогда
ОбщегоНазначенияКлиентСервер.СообщитьПользователю(ТекстСообщения);
Иначе
УровеньЖР = ?(УровеньЖР=Неопределено, УровеньЖурналаРегистрации.Информация, УровеньЖР);
ЗаписьЖурналаРегистрации(НСтр("ru='oData Выгрузка контрагентов и банковских счетов'"), УровеньЖР,
ЭтотОбъект.Метаданные(),, ТекстСообщения);
КонецЕсли;

КонецПроцедуры

Процедуру ОписаниеВнутреннегоКодаОшибкиOData сдернул откуда-то из просторов Интернет, к сожалению не помню автора, но спасибо выражаю.

В довершение добавлю, что на релизе платформы 8.3.10.2252 мне так и не удалось корректно записать через oData в приемнике запись независимого регистра сведений, перепробовал уйму вариантов, в т.ч. и через XML – стабильная ошибка 500, поэтому когда встала срочная задача сделать POST я реализовал через HTTP-сервис в приемнике. Если у кого-нибудь есть рабочие примеры — приведите плиз.

Для получения теоретического базиса и информации по публикации базы на web-сервере категорически рекомендуется прочесть:

https://its.1c.ru/db/v8311doc#bookmark:dev:TI000001358

https://its.1c.ru/db/v8311doc#bookmark:dev:TI000001426

//infostart.ru/public/711302/

//infostart.ru/public/565435/

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

Код прилагаю в виде внешней обработки, с вопросами обращаемся)

55 Comments

  1. fr13

    По мне так слишком сложно в реализации. Куда проще сделать все через SOAP и план обмена

    Reply
  2. timm00

    (1) Да Николай, SOAP проще. Но. SOAP требует наличия SOAP-сервисов на стороне клиента, и производительность обмена ниже. У меня например любой обмен не занимает более 1,5 секунд при условии что происходит инициализация сеанса. А получение данных — вообще чудо производительности, обходит COM в десятки раз.

    А вот планы обмена я просто недолюбливаю, считайте это эксцентрикой)

    Reply
  3. gradi

    (2)

    обходит COM в десятки раз

    Это все хорошо, когда есть возможность опубликовать базу на веб-сервере. Без этого только СОМ.

    Reply
  4. webresurs

    здорово!

    Подскажите пож. в БП 3.0 через настройку OData включил доступ к документу платежное поручение и теперь надо в браузере получить документы за определенный период:

    /odata/standard.odata/Document_ПлатежноеПоручение$format=json&$select=Number­,Date,Организация_Key,Контрагент,СуммаДокумента,НазначениеПлатежа,Комментарий,ДокументОснование_Type&$filter=Date(StartPeriod=datetime’2018-03-19T00:00:00′,EndPeriod=datetime’2018-03-19T23:59:59′)

    выдает ошибку: не найдена , что не так подскажите?

    Reply
  5. timm00

    (3) Апач помогает если с лицензиями заморочка)

    Reply
  6. timm00

    (4) Знак вопроса забываете)

    /odata/standard.odata/Document_ПлатежноеПоручение?$format=json&$select=Number ,Date,Организация_Key,Контрагент,СуммаДокумента,НазначениеПлатежа,Комментарий,ДокументОснование_Type&$filter=Date(StartPeriod=datetime’2018-03-19T00:00:00′,EndPeriod=datetime’2018-03-19T23:59:59′)

    Reply
  7. swimdog

    Только труЪ COM ))

    Reply
  8. gradi

    (5) заморочка с админами.

    Reply
  9. kare

    (8)и с службой безопасности )

    Reply
  10. zarucheisky

    (2) Вы хоть «ИМХО, в моём случае» добавляйте, а то так категорично судить что тормоз/шустро 🙁

    Reply
  11. Bright Sun

    Мы сделали небольшой веб-сервис облегчающий генерацию OData-запросов по любой Конфигурации.

    http://gen.bi-team.ru/GQ

    Структуру метаданных можно передать как через файл ($metadata) так и через доп Обработку, которую можно запросить с ресурса http://bi-team.ru/

    Reply
  12. webresurs

    (6) — ошибка

    {
    «odata.error»: {
    «code»: «14»,
    «message»: {
    «lang»: «ru»,
    «value»: «Ошибка при разборе опции запроса $filter»
    }
    }
    }

    Показать

    Reply
  13. webresurs

    (6) воспользовался ссылкой из (12)

    /odata/standard.odata/Document_ПлатежноеПоручение?allowedOnly=true&$select=Number,Date,Контрагент,СуммаДокумента,НазначениеПлатежа,Комментарий,ДокументОснование_Type&$filter=Date ge datetime’2018-04-02T00:00:00′ and Date le datetime’2018-04-02T23:59:59′
    Reply
  14. webresurs

    (12) — спасибо

    — поделитесь обработкой с «gen.bi-team.ru/GQ » на infostar ?

    Reply
  15. timm00

    (14)

    allowedOnly=true&

    нужно убрать. Или добавить $

    Reply
  16. androgin

    (12) Я, конечно извиняюсь, но ваша ссылка дает мне возможность почитать содержимое компа с установленной 1С ))))

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

    Никто не мешает мне прям сейчас сменить там пароль и заблокировать ваш комп )))))

    Закройте «Все функции» )))

    Reply
  17. zhuntovda

    (17)

    Выборка = Запрос.Выполнить().Выбрать();

    Просветите, почему?

    Reply
  18. Артано

    (19) Мусье педант, и не принял к сведению оговорку автора, что код писался на коленке за «полдня».

    Увольнять за такое конечно не стоит, а вот делать замечание да

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

    Reply
  19. Bukaska

    (20) Чего то я тоже не догоню, когда это выборка стала вдруг такой нелюбимой? Или вопрос в другом?

    Reply
  20. Артано

    (21) Я полагаю, что комментатору за номером 17 не понравилось отсутствие промежуточной переменной типа РезультатЗапроса. По крайней мере мне тоже не понравилось бы, но своё отношение я высказал ранее

    Reply
  21. Bukaska

    (22)Ну я так и подумала, что либо промежуточная переменная, либо то, что в выборке можно было обойти результат не только напрямую.

    Reply
  22. webester

    (17)Может есть хоть, что-то по существу, почему за это надо убивать?

    Я конечно выгляжу совсем как дурак, но мне совершенно непонятно.

    (22)Ну нет, промежуточной переменной. Почему это плохо?

    Еще неплохо уволить тех, кто писал СП, там такие примеры Хранилище = Новый ХранилищеЗначения(Значение, Новый СжатиеДанных(9));

    Reply
  23. webester

    (18)Подозреваю у пользователя, от имени которого выполняется веб сервер или 1с(не знаю от чего имени выполняется код) скорее всего нет на это прав, не пароли менять, не еще какие либо непотребства вершить. Я полазил по машине, это скорее всего развернутая виртуалка, Хотя… судя по тому, что есть юзер2 в списке пользователей… Не надо меня только увольнять меня за код на коленке 🙂 написал быстренько, некогда возиться, просто ради спортивного интереса

    Reply
  24. webester

    (26)У вас увольняют за отсутсвие экономии полтакта процессора(или сколько занимает времени создание выборки)? Боюсь даже предположить, что бывает за не по стандарту оформленные комментарии. Или вдруг если отсуп забыл поставить. Просто сразу убивают наверное.

    Reply
  25. androgin

    (23) и снова мимо

    Reply
  26. androgin

    (22) ошибаетесь

    Reply
  27. androgin

    (20) Если уж и писать код, то его нужно хотя бы почитать после завершения.

    Никто ведь не мешал сделать корректировки ))

    Учитывая, что тут сидят критики и похлеще)

    Оговорка «на коленке» тут не прокатит, по выше_озвученным причинам

    Reply
  28. androgin

    (25) «скорее всего нет на это прав» — это не смущает? ))

    Я вот точно за свой сервер могу сказать у кого какие права)

    Reply
  29. webester

    (32) Конечно не смущает. Это не мой сервер. Я не знаю, есть там права или нет. Проверять лень. Да и вредить неохота.

    Reply
  30. Артано

    (26) Инициализация самой выборки практически бесплатна, выборка это просто объект который работает с результатом запроса, никаких данных в нем нет. Там конечно не полтакта, но не всегда различимое даже на уровне тысячных долей секунды время. Придирка и мера наказания неадекватны.

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

    Reply
  31. webester

    (34)

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

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

    (34)

    И все эти «мелочи» всегда выливаются в производительность.

    Это не так. Миллионы строк кода которые выполняются просто при открытии формы списка или формы объекта в современных типовых влияют на производительность. Идите писателей типовых увольняйте. Но даже в этом случае создание пустых выборок или их отсутсвие никак бы не изменило ситуацию. Создание пустых выборок вообще никак и никогда не меняет ситуацию. а ваши едкости — показатель вашей личности, а не качество чьего-то кода. Какое-то раздувание щёк на ровном месте.

    Reply
  32. Bukaska

    (26)Что -то мне кажется, что УЦ обычно как раз преподают именно тот вариант, за который вы бы уволили. Если это только не курсы спеца)))

    Reply
  33. Hamsik

    (28) Вас в своё время уволили? К чему такая «токсичность» ? Может детская травма?

    Reply
  34. Артано

    (26) И к слову о производительности. Ну допустим так. И запрос не пустой? Еще раз сделаете запрос выполнить? Ну и кого увольнять/убивать/насильничать? Была давным-давно такая реклама с хорошим слоганом: «иногда лучше жевать чем говорить».

    Reply
  35. Артано

    (38) Это просто психологическая компенсация собственной некомпетентности. Пишешь говнокод, страдаешь от этого, но нахватался верхушек на курсах? Есть выход — зайди на форум и обгадь код придравшись к несущественной мелочи.

    Reply
  36. androgin

    (39) вот в вашем случае как раз лучше жевать))

    Сходите в 1С и сдайте экзамен. будет лучше и убедительней, чем ваши визги

    Reply
  37. androgin

    (37) Покреститесь, чтобы не казалось

    Reply
  38. Hamsik

    (41) Все же к оскорблениям переходить не стоит, я думаю правила форума к этому располагают, а в Вашем огромном таланте никто не сомневается.

    Reply
  39. androgin

    (38) в мое время учили грамотно, чтобы не уволили. А вас видимо пора)))

    Reply
  40. Hamsik

    (46) Хорошо, видимо пора идти писать заявление, в чем провинился сударь ?

    Reply
  41. androgin

    (47) ну так вот с себя и начните. А я пока ни слова оскорбления не сказал)

    Reply
  42. Hamsik

    (50) Надеюсь модераторы форума оценят ваши аргументированные доводы

    Reply
  43. webester

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

    https://monosnap.com/image/gSH6lPc1TNIrNeVwGq0wNS97z7RoBo.png

    Что же вы особо одаренный (44) перед выборкой не проверили, вдруг результат запроса пустой? Чуть ли не единственный запрос на всю конфигурацию и сразу такой ляп. Вы уже пишете заявление или просто мимокрокодил?

    Reply
  44. androgin

    (51) Оценят, не сомневайтесь)

    Reply
  45. webester
    О, да, Эта обработка была сделана, как раз в пример одного дяди (вроде вас), который усирался, что нельзя фоном выводить сообщения.

    Вообще наплевать, для чего или кого она сделана. Можно не оправдываться.

    (52)

    И код там в принципе его заимствован и не представляет интереса

    Не не не так не пойдет: Тут в (31) человек явно говорит, что код должен быть написан сразу идеально

    Никто ведь не мешал сделать корректировки ))

    оговорки тут не катят по вышеозвученным причинам.(с)31

    Наслаждайтесь )))

    о да, уже 🙂

    Reply
  46. webester

    (53)

    как раз в пример одного дяди (вроде вас)

    Мы уже поняли, что вы один тут дартаньян

    Reply
  47. webester
    Reply
  48. rozaliya1606

    (26)

    Приведенный вами также не корректен — приведет к выполнению запроса 2 раза,

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

    если уж на то пошло следует объявить переменную и проверять в условии РезультатЗапроса.Пустой()

    Reply
  49. Dementor

    Отличная статья! И спасибо за упоминание моей заметки про чтение через oData. (вы же в курсе, что было продолжение про запись?). У меня в плане были еще парочка статей на данную тему для покрытия вопроса, но, к сожалению, участие в паре параллельных проектов забирает абсолютно все время. А ведь как раз хотел поэкспериментировать с регистрами сведений, накопления, бухгалтерии и расчета. А еще была задумка по работе с планом обмена (а-ля РИБ через веб). Может летом продолжу…

    На злостных комментаторов не обращайте внимания. Я упомянутых проблем в коде не увидел 😉

    Если интересны рекомендации, то не нужно мучиться при наличии чисел со строковыми ключами в структурах — сразу применяйте соответствие. Но с точки зрения быстродействия лучше было написать через Если… ИначеЕсли… КонецЕсли. (переписывать не нужно)

    Reply
  50. Bassgood

    (17) Судя по всем вашим комментариям и отношению к окружающим, могу с уверенностью сказать, что к руководящей должности Вас никто не допустит и под вашим началом работать никто не захочет, так что такая возможность Вам никогда не предоставится, а скорее наоборот — увольнять будут именно Вас 😉

    p.s. Думаю аналогичного мнения о Вас придерживаются и ваши коллеги, если конечно они у Вас имеются

    Reply
  51. Bassgood

    (44) Специально для Вас объясню о чем на самом деле идет речь в приведенной Вами рекомендации с диска ИТС:

    В данном случае имеется ввиду получение данных из результата запроса либо выборкой (через ее метод «Следующий()»), либо выгрузкой в ТЗ (через метод «Выгрузить()» результата запроса), о чем четко написано в тексте рекомендации.

    Инициализация объекта «Выборка» и получение через нее данных методом «Следующий» (именно о нем идет речь в рекомендации) — разные вещи!

    1. «Выборка = Запрос.Выполнить().Выбрать();» — инициализация объекта, речь в рекомендации не об этом

    2. «Выборка.Следующий()» — получение данных в объект выборки, именно об этом идет речь в рекомендации (не говоря уже о выгрузке в ТЗ)

    Проверка наличия данных в результате запроса:

    1. «Запрос.Выполнить().Пустой()» — верно

    2. «Запрос.Выполнить().Выбрать().Следующий()» — неверно

    3. «Запрос.Выполнить().Выгрузить().Количество() = 0» — неверно

    А то что Вы не смогли объяснить это представителю УЦ 1С, а судя по всему не смогли этого сделать потому что сами не поняли сути рекомендации — так это говорит только о Вашей некомпетентности, именно поэтому и снимают балл на экзамене.

    Reply
  52. androgin

    (63)

    Запрос.Выполнить().Выгрузить()

    вот это уже затратно!

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

    мыслите шире, а не шаблонами.

    Я смотрю у вас минимум практики

    Reply
  53. Bassgood

    (64) Выгрузку в ТЗ я привел Вам в качестве примера неверного использования проверки наличия данных в результате запроса, или Вы читали мой комментарий по диагонали, ровно также как и приведенную Вами рекомендацию с ИТС?

    Я смотрю у вас минимум практики

    Судя по тому, что Вы не понимаете сути рекомендации, которую сами же и приводите в качестве довода своей правоты, практики не хватает как раз именно Вам 😉

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

    Reply
  54. hudyakov74

    в 8.3.13.1690 запись в независимый периодический спокойно делается

    только это поправлено как отмечали выше

    ЗаголовокHTTP = Новый Соответствие();

    ЗаголовокHTTP.Вставить(«Accept», «application/json»);

    ЗаголовокHTTP.Вставить(«Content-Type», «application/json; charset=utf-8»);

    кстати когда Apache Olingo прикручивал — чувствительно было к записи пустых ссылок — обязательно 00000000-0000-0000-0000-000000000000 заполнять.

    Reply
  55. ImHunter

    (0) (66) Тоже копаюсь с oData. С независимым РС были определенные проблемы — не читался с отбором по записи, не писался. Это было на 8.3.10.2580, опубликованной на IIS 6. Выдавало HTTP Error 400. The request URL is invalid.

    Помогла публикация базы на апаче.

    Reply

Leave a Comment

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