Open Data Protocol (OData)
7 причин почему интеграция стала приятной.

В статье показаны примеры получения данных без программирования на стороне «1С:Предприятие 8». Вам нужно проверить гипотезу и проанализировать данные, почему бы не интегрироваться с Excel? Используете технологии .NET и «1С:Предприятие 8», процесс связывания систем движется катастрофически медленно? Хотите native Android приложение с вашими данными всегда под рукой?

Введение в Open Data Protocol

В 1С Предприятие 8.3.5.1068 появилась поддержка автоматического REST-сервиса. Теперь платформа может автоматически формировать REST интерфейс для всего прикладного решения. Вы привычным образом публикуете его на веб-сервере и после этого сторонние системы могут обращаться к вашему приложению с помощью HTTP запросов. В качестве протокола доступа платформа использует протокол OData версии 3.0. Это открытый веб-протокол для запроса и обновления данных. Он позволяет оперировать данными, используя в качестве запросов HTTP-команды. Получать ответы можно в различных форматах, но пока присутствует поддержка формата Atom/XML.

7 причин, почему интеграция стала приятной

  1. платформа автоматически генерирует REST интерфейс, не нужно никакого программирования;
  2. прозрачная интеграция прикладного решения с интернет-сайтами, мобильными приложениями и прочими системами;
  3. реализация сторонними средствами дополнительной функциональности без изменения конфигурации;
  4. загрузка данных в прикладное решение и выгрузка данных из него;
  5. управление составом объектов метаданных, доступных через стандартный сервис OData API на лету;
  6. ограничения прав доступа пользователей также действительны для запросов OData;
  7. универсальность и кроссплатформенность.

Подготовительный этап

  1. версия платформы «1С:Предприятие 8» — не ниже 8.3.5.1068;
  2. режим совместимости конфигурации — «Не использовать» или не ниже «Версия 8.3.5»;
  3. включен флаг «Публиковать стандартный интерфейс OData«;
  4. определеть состав объектов метаданных, доступных через стандартный сервис OData;
  5. проверить работоспособность сервиса по ссылкам:
    http://{АдресВебСервера}/{ИмяПубликации}/odata/standard.odata;
    http://{АдресВебСервера}/{ИмяПубликации}/odata/standard.odata/$metadata;
  6. посмотреть проходит ли валидацию описание сервиса по ссылке.

Возникают трудности? Посмотрите видео:

Если возникают проблемы с валидацией, нужно обратится по адресу https://partners.v8.1c.ru/forum/. Использовать веб-сервис все равно можно, даже если валидация не удалась.

Обработка для определения состава метаданных, доступных через стандартный сервис OData, доступна по ссылке Google Drive.

Интеграция с Excel

Бывают случаи, когда нужно получить данные из информационной базы «1С:Предприятие 8» и быстро обработать их. Работая с бизнес-аналитиками, руководителями потребность в данных есть всегда. Чаще всего информацию получить сложно без привлечения программиста, да и процесс передачи понимания что же нужно не так прост. С помощью стандартного сервиса OData, можно получать данные прямо в Excel, использовать все возможности Excel для анализа данных, построения моделей, формирования сводных таблиц и т. п. Самое приятное, что все расчеты будут автоматически обновляться при изменении данных в «1С:Предприятие 8». Рассмотрим поэтапно:

  1. нужно настроить внешний источник данных в ExcelПодключение из Excel к «1С:Предприятие 8»
  2. настроить подключение к REST сервису «1С:Предприятие 8»
    Вводим ссылку на описание сервиса OData, логин и пароль
  3. отмечаем нужные таблицы, в примере «Справочник.Валюты» и «РегистрСведений.КурсыВалют»
    Отмечаем нужные данные
  4. импортируем данные из «1С:Предприятие 8»
    Импортируем данные из «1С:Предприятие 8»

Для получения детальной информации посмотрите видео:

Интеграция с .NET системами

Ни для кого не секрет, что появляется множество новых систем с которыми нужно интегрироваться. На живом примере видел, что связывание систем очень долгий и сложный процесс. Почему бы его не упростить? Сделаем программу на c# (Windows Forms Application), которая будет выводить курсы валют. Рассмотрим поэтапно:

  1. необходимый инструментарий: Microsoft Visual Studio (в примере используется Visual Studio Community 2015), DataSvcUtil.exe (обычно идет вместе с Visual Studio Community 2015);
  2. сохраним описание REST сервиса в файл metadata.csdl;
  3. с помощью утилиты DataSvcUtil.exe сформируем прокси класс, которые будет делать всю работу по взаимодействию с REST сервисом «1С:Предприятие 8». Вот так выглядит командная строка:
    C:\Users\Designer>»C:\Program Files (x86)\Microsoft WCF Data Services\5.6.4\bin\tools\DataSvcUtil.exe» /in:D:\Public_OData\metadata.csdl /out:D:\Public_Odata\metadata.cs /version:3.0;
  4. создаем проект Windows Forms Application
    Создаем проект Windows Forms Application
  5. добавляем в проект прокси класс metadata.cs;
  6. в файле App.config пропишем параметры доступа к REST сервису:
        <add name="ProductionOData" connectionString="http://wall-e.ktc.local/dt/odata/standard.odata" />
        <add name="UserOData" connectionString="username" />
        <add name="PasswordOData" connectionString="password" />
    
    
  7. добавим необходимые References в проект
    Необходимые References
  8. добавим на форму DataGridView и настроим
    Добавляем DataGridView
  9. при загрузке формы добавим код для получения курсов валют из REST сервиса:

    // Получаем ссылку на REST сервис
    Uri serviceRoot = new Uri(ConfigurationManager.ConnectionStrings[«ProductionOData»].ConnectionString);

    // Инициализируем сервис
    EnterpriseV8 V8Base = new EnterpriseV8(serviceRoot);

    // Задаем пользователя и пароль в «1С:Предприятие 8»
    V8Base.Credentials = new NetworkCredential(ConfigurationManager.ConnectionStrings[«UserOData»].ConnectionString,
    ConfigurationManager.ConnectionStrings[«PasswordOData»].ConnectionString);

    // Получаем список значений справочника валюты
    List<Catalog_Валюты> currencyCatalog = new List<Catalog_Валюты>();
    IEnumerable<Catalog_Валюты> currencyResponse = V8Base.Catalog_Валюты.Execute();
    foreach (var item in currencyResponse)
    {
    currencyCatalog.Add(item);
    }

    // Выводим курсы валют в dataGridView, подставляя Description из списка значений справочника валют
    IEnumerable<InformationRegister_КурсыВалют> coursesResponse = V8Base.InformationRegister_КурсыВалют.Execute();
    foreach (var item in coursesResponse)
    {
    string[] record =
    {
    item.Period.ToString(),
    currencyCatalog.Find(x => x.Ref_Key == item.Валюта_Key).Description,
    item.Курс.ToString()
    };
    dataGridView2.Rows.Add(record);
    }

  10. Запускаем на выполнение и любуемся
    Результат выполнения
Для получения детальной информации посмотрите видео:

Интеграция с системами на базе Android

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

  1. решения для увеличения продаж;
  2. вся информация о вашей компании в смартфоне клиентов;
  3. важные показатели бизнеса всегда под рукой;
  4. улучшение качества бизнес-процессов;
  5. продвижение своего приложения позволяет компании повысить собственный имидж.
Чем native приложение лучше 1С мобильного приложения? Native приложение позволяет поддерживать высокую производительность, обрабатывать больше данных на стороне клиента, нет очень жестких ограничений, как при разработке 1С приложения, а самое главное среда разработки для Android развивается в разы быстрее. Из личного опыта, внедрение мобильного приложения в систему логистики, по доставке товаров и приема оплаты от клиентов, позволило обрабатывать в десятки раз больше заказов без ошибок и недоездов. Показательно, что в сезон продаж рост был четырёхкратный и система отработала безотказно.
Сделаем мобильное приложение Android, которое будет выводить курсы валют. Рассмотрим поэтапно:
  1. необходимый инструментарий: Eclipse JAVA (создание прокси класса для взаимодействия с REST сервисом «1С:Предприятие 8»), библиотеки restlet.org (JAVA SE, Android) и Android Studio для создания приложения;
  2. создаем новый проект в Eclipse -> Java Project. Добавляем необходимые внешние библиотеки restlet.org (JAVA SE):
    • org.restlet.jar
    • org.restlet.ext.odata.jar
    • org.restlet.ext.freemarker.jar
    • org.restlet.ext.atom.jar
    • org.restlet.ext.xml.jar
    • org.freemarker_2.3\org.freemarker.jar
  3. к сожалению, библиотека org.restlet.ext.odata.jar не умеет создавать прокси классы из файлов *.csdl и REST сервисов, где необходима авторизация. Покопавшись в исходниках Restlet, добавил возможность прохождения авторизации REST и дальнейшей генерации прокси классов, новая версия библиотеки есть в архиве в конце статьи. Официально, пока не известно когда мои изменения попадут в основную ветку Restlet, обсуждение этой задачи здесь;
  4. добавим код формирования прокси классов:
    import java.net.URI;
    
    import org.restlet.data.ChallengeResponse;
    import org.restlet.data.ChallengeScheme;
    import org.restlet.data.Reference;
    import org.restlet.ext.odata.Generator;
    
    public class Main {
         
        public static void main(String[] arg) throws Exception
        {
            String serviceURL = "http://wall-e.ktc.local/dt/odata/standard.odata";
            Generator ODataGen = new Generator(new Reference(URI.create(serviceURL)), "ODataConnector");
            ODataGen.setCredentials(new ChallengeResponse(ChallengeScheme.HTTP_BASIC, "username", "password"));
            ODataGen.generate("D:\\Public_OData\\eclipse\\proxy_generated\\");
    
        }
    }
    
  5. запускаем, через несколько мгновений классы должны быть готовы;
Возникают трудности? Посмотрите видео:

  1. создаем новый проект в Android Studio, заполняем все необходимые поля;
  2. переходим в каталог проекта, далее в директорию mobile\libs\, копируем внешние библиотеки restlet.org (Android):
    • org.restlet.jar
    • org.restlet.ext.odata.jar
    • org.restlet.ext.atom.jar
    • org.restlet.ext.xml.jar
      Копируем библиотеки Restlet в проект
  3. возвращаемся в корень проекта и переходим в mobile\src\main\res\layout\, добавляем описание layout item.xml, который будем использовать для вывода данных в gridView. Описание item.xml:
    
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <TextView
            android:id="@+id/tvText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center_vertical"
            android:minHeight="40dp"
            android:textSize="20sp"
            android:text="">
        
    
    
  4. в файл mobile\src\main\AndroidManifest.xml добавляем строки, связанные с доступом приложения (перед блоком ):
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <permission android:name="android.permission.INTERNET"/>
    
  5. в файл \mobile\build.gradle добавляем строки связанные с внешними библиотеками restlet.org (Android), чтобы включить их сборку проекта:
    dependencies {
        compile fileTree(include: ['*.jar'], dir: 'libs')
        wearApp project(':wear')
        compile 'com.android.support:appcompat-v7:23.0.1'
        compile 'com.google.android.gms:play-services:7.8.0'
        compile files('libs/org.restlet.ext.odata.jar')
        compile files('libs/org.restlet.ext.xml.jar')
        compile files('libs/org.restlet.jar')
        compile files('libs/org.restlet.ext.atom.jar')
    }
    
  6. создаем папку ProxyClass в \mobile\src\main\java и копируем в нее файлы созданные на 5 шаге:
    Копируем прокси класс в проект
  7. добавляем в файл StandardOdataService.java, запись:
    package ProxyClass;
    
  8. во все файлы в папке \mobile\src\main\java\ProxyClass\standardodata добавим следующее:
    package ProxyClass.standardodata;
    
  9. к сожалению, библиотека Restlet не знает такой тип, как TypeCollection(Edm.String)« и формирует прокси класс с ошибкой, создавая неизвестный тип CollectionStringEdm. Переходим в файл \mobile\src\main\java\ProxyClass\standardodata\TypeDescription.java и заменяем CollectionStringEdm на List;
  10. исправляем ошибки namespace’ов в файлах прокси класса;
  11. в Android Studio на активити добавляем gridView и настраиваем:
    Добавляем gridView и настраиваем
  12. вот так выглядит процедура при создании:
     @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
            StrictMode.setThreadPolicy(policy);
    
            setContentView(R.layout.activity_main);
    
            /* Инициализируем OData сервис */
            StandardOdataService service = new StandardOdataService();
            service.setCredentials(new ChallengeResponse(ChallengeScheme.HTTP_BASIC, "username", "password"));
    
            /* Создаем соответствие межу GUID'ом валюты и ее Description */
            Map<String, String> hashTable = new HashMap<String, String>();
            Query<Catalog_Валюты> currencyCatalog = service.createCatalog_ВалютыQuery("/Catalog_Валюты");
            for (Catalog_Валюты data : currencyCatalog) {
                hashTable.put(data.getRef_key(), data.getDescription());
            }
    
            /* Подготавливаем заголовки таблицы */
            List<String> listData = new Vector<String>();
            listData.add("Период");
            listData.add("Валюта");
            listData.add("Курс");
    
            /* Получаем курсы валют, СрезПоследних(), и добавляем в список для вывода * подставляем Description из соответствия валют */
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
            Query<InformationRegister_КурсыВалют> coursesResponse = service.createInformationRegister_КурсыВалютQuery("/InformationRegister_КурсыВалют/SliceLast");
            for (InformationRegister_КурсыВалют data : coursesResponse) {
                listData.add( formatter.format(data.getPeriod()));
                listData.add( hashTable.get(data.getВалюта_key()));
                listData.add( Double.toString(data.getКурс()));
            }
    
            /* Выводим данные на активити */
            ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.item, R.id.tvText, listData);
            GridView dataGridView = (GridView)findViewById(R.id.gridView);
            dataGridView.setAdapter(adapter);
    
        }
    

Возникают трудности? Видео 6-17 шагов:

Послесловие

Интегрироваться с «1С:Предприятие 8» стало на порядок проще, надеюсь информация будет полезна сообществу.

Исходные коды .NET Google Drive
Исходные коды JAVA Google Drive

Автоматически генерируемый REST интерфейс прикладных решений 1С:Предприятия

Средства работы с JSON

Расширение поддержки протокола OData

От pbazeliuk

15 комментарий для “7 причин, почему интеграция стала приятной. Не упускайте ряд потрясающих возможностей”
  1. Замечательная статья! Спасибо.
    Но… Попытался подключиться из VS2015 к REST от 1С:ЗУП, наппоролся на какойто косяк. Не могу сделать класс метаданых, DataSvcUtil выдает ошибку:

    error 7001: The element ‘Key’ in namespace ‘http://schemas.microsoft.com/ado/2007/05/edm’ has incomplete content. List of possible elements expected: ‘PropertyRef’ in namespace ‘http://schemas.microsoft.com/ado/2007/05/edm’.

    Не подскажете в каком направление поискать решение.
    Спасибо.

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

  2. […] набросок является продолжение предыдущей статьи 7 причин, почему интеграция стала приятной. Не упускайт…. В большей части это описание боли через которую […]

  3. Добрый день! Спасибо за статью. Сделал все по примеру, только создал веб приложение.
    При попытке получить данные идет ошибка 401 unauthorized. В чем может быть проблема ?
    Возможно ли, что из-за недостатка прав ?

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

        1. Доброго времени суток. Возможно, вы не добавили доступ к необходимым метаданным которые пытаетесь получить через OData интерфейс. Попробуйте использовать обработку и дать доступ полностью ко всей конфигурации https://drive.google.com/file/d/0B4eCXs0iu1raN09ZbU1IVjFlOFE/view

          1. Доброго времени суток. Использовал обработку. А возможно ли такое, что веб сервер блокирует доступ?

            1. Сложно понять, что на самом деле происходит.
              Попробуйте воспользоваться http://www.telerik.com/fiddler. Программу необходимо запускать на том же компьютере с которого вы пытаетесь зайти и соответственно с ней можно проанализировать и отладить запросы которые посылаются к базе данных 1С:Предприятие.
              Желательно использовать для отладки простое HTTP соединение, шифрованное соединение — после того, как уже будет работать при обычном соединении.

  4. Может показать пример как отправить данные с андройда(java) на сервер 1с, в формате json, заранее спасибо.

    1. На самом деле, я не программирую на java, все что написано в статье сделано по аналогии с помощью знаний .NET. Я подозреваю, что результат будет выглядеть как-то так:

      using (HttpClient client = new HttpClient())
      {
          client.Timeout = TimeSpan.FromMinutes(1);
          client.DefaultRequestHeaders.Authorization = authenticationHeader;
      
      var cts = new CancellationTokenSource();
      try
      {
          using (HttpResponseMessage response = await client.PostAsync(
              RequestUri, new StringContent(message), cts.Token))
          {
              if (!response.IsSuccessStatusCode)
              {
                  var errorMsg = await response.Content.ReadAsStringAsync();
                  ...
              }
          }
      }
      catch (WebException ex)
      {
          ...
      }
      catch (TaskCanceledException ex)
      {
          ...
      }
      catch (Exception ex)
      {
          ...
      }
      finally
      {
          ...
      }
      
      
      }

Добавить комментарий

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