Добрый день. Коллеги.
Помогите найти оптимальный алгоритм решения задачи.

Исходные данные
1. Конфигурация» 1С Альфа-Авто: Автосалон +Автосервис + Автозапчасти. Редакция 4.1» на обычном приложении.
2. Платформа 1С:Предприятие 8.2 (8.2.19.83) MSSQL.
3. Есть мобильное приложение с базой данных MySQL.

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

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

Структура таблицы MySQL:
1. Модель автомобиля
2. Менеджер
3. Пробег От (критерий нормы выполнения тех. обслуживания)
4. Пробег До (критерий нормы выполнения тех. обслуживания)
5. Дата
6. Время записи (интервалы по часу)

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

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

Мы не можем взять все записи и поместить их в MySQL.
Есть два решения, которые я смог найти в интернете.
1. Объектная запись во «Внешний источник данных».
2. Выполнение текста запроса ADODB.Connection командой ADODB.RecordSet
Вариант №1 не можем использовать, вследствие того, что подобные возможности появились только в платформе 1С:Предпряитие 8.3.6. А перевод конфигурации на обычном приложении (которую в свою очередь переписывали «горе» программисты) на платформу 1С:Предпряитие 8.3.6 – достаточно авантюрное мероприятие.

Исходя из выше написанного мы принялись писать алгоритм под Вариант №2 но столкнулись со следующими проблемами:

Проблема №1. «Преобразование типов значений к MySQL».
Преобразование типов производиться в цикле, к сожалению в Запросы 1C не обладают возможностями конвертации значений в необходимый форматы, которые понимает MySQL.
Пример функций конвертации:

```1c
    ТипыЗначенийИАлгортимыКонвертацииТиповMySQL = Новый Структура;

    ТипыЗначенийИАлгортимыКонвертацииТиповMySQL.Вставить("INT_", "ЗначениеMySQL = Формат(Значение1C, "ЧРД=.; ЧРГ=; ЧН=0; ЧГ=0")");
    ТипыЗначенийИАлгортимыКонвертацииТиповMySQL.Вставить("VARCHAR_","ЗначениеMySQL = Строка(Значение1C)");
    ТипыЗначенийИАлгортимыКонвертацииТиповMySQL.Вставить("DATE_", "ЗначениеMySQL = Формат(Значение1C, "ДФ=yyyy-MM-dd")");
    ТипыЗначенийИАлгортимыКонвертацииТиповMySQL.Вставить("TIME_", "ЗначениеMySQL = Формат(Значение1C, "ДФ=ЧЧ:мм:сс")");
    ТипыЗначенийИАлгортимыКонвертацииТиповMySQL.Вставить("ID_", "ЗначениеMySQL = Строка(Значение1C.УникальныйИдентификатор())");
    ТипыЗначенийИАлгортимыКонвертацииТиповMySQL.Вставить("TINY_", "ЗначениеMySQL = Строка(Значение1C)");
```

В таблице запроса, который выполняется 53 сек, содержится 190 000 записей. Преобразование типов значений занимает 120 сек., что в два раза дольше выполнения запроса 1С из 50 временных таблиц!!!

Формирование текста запроса MySQL
Формирование текста запроса, какой бы банальной не казалась задача, занимает 300 сек, и содержит 12 миллионов символов, что в шесть раз дольше выполнения запроса 1С.

Проблема №3. «Выполнение команды записи данных MySQL».
Выполнение 19 запросов (первоначально был один, но с целью оптимизации разделен на 1 запрос для 10 000 записей) , выполняется 130 сек.

Итого
Выполнение запроса 1С – 53 сек
Преобразование типов значений к MySQL – 120 сек
Формирование текста запроса MySQL – 300 сек
Выполнение команды записи данных MySQL – 130 сек

Подскажите, пожалуйста, как творчески решить поставленную задачу:?
Есть вариант создать таблицу в 1С, записывать данные в нее, а мобильное приложение по средствам подключения к базе данных MS SQL 1C будет вытягивать необходимые данные.
---
Задачи интеграции нужно решать не творчески, а согласно best practices.

1) Объемы результата запроса наводят на мысль, что в нем куча избыточных данных. Обрежьте период согласно требованиям бизнеса, а доступность менеджеров и подъемников разнесите по разным таблицам. Сделайте процесс выбора момента записи последовательным.
2) Конструктивно для интерграции с внешними системами предназначены веб и http - сервисы. В этом случае всю бизнес-логику можно будет реализовать на стороне 1С, что значительно гибче. Грубо говоря, вам нужно два метода:
а) По указанным дате и менеджеру получить график доступности
б) Занять поле графика доступности

3) Запрос на 190000 строк, выполняемый 53 секунды - это не кажется нормальным. Смотрите в план, скорее всего, у вас там либо скан, либо ошибка прогнозирования.
4) При преобразовании данных откажитесь от динамического кода, статический исполняется быстрее.
---
non1ka, так, на вскидку... можно подумать в сторону web-сервисов на 1С.
Еще вариант, использовать скриптовый язык (типа python), вытягивать нужные данные из 1С (можно прямо из mssql) и формировать записи в базу mysql.
---
spacecraft,
  так, на вскидку... можно подумать в сторону web-сервисов на 1С.
Да, действительно. Этот вариант мне кажется наиболее интересным.
Но, когда я сталкивался с Мобильными приложениями от фирмы 1С.
Вся синхронизация в этих решения производилась по средствам обмена XDTO-пакетами, которые так же циклами и выборками формировались.

Подскажите, где можно почитать о Web-сервисах.

(4) CaptainMorgan,
Вопрос. Вы говорите про такой код?

Совершенно верно.

Я бы предложил следующий подход.
Хранить данные на web-сервере. (Формат базы любой, хоть тот же MySQL)
А 1С, с определённой периодичностью, обращается к web-серверу по средствам post запроса и актуализирует данные.
Мобильное приложение, так же post-запросом получает актуальные данные с сервера и обновляет свою базу данных.

Очень интересное решение. Подскажите, где можно более подробно изучить методологию?

(5) Xershi,
почему не используете мобильное приложение от 1С?

Мобильное приложение разрабатывается в маркетинговых целях, и должно обладать функционалом рассылки Push-уведомлений, Геолокаций, Стиль и интерфейс приложения должен соответствовать бренд-буку компании и т.п. Интеграция с 1С лишь десятая часть проекта, а возможности платформы 1С, к сожалению, на данный момент не позволяют решить все задачи проекта.
---
non1ka, только стилизация в приложении вам помеха.
Ну, а по поводу запроса. То наверно вам нужно хранить в базе уже готовые варианты бронирования. И синхронизировать их. А не делать сложные вычисления на основе базы.
---
Очень интересное решение. Подскажите, где можно более подробно изучить методологию?
Я web-сервер, для примерно подобного проекта писал на php, собственно, в качестве документации удобно использовать любой учебник php.
post или get запросы будет формировать 1С - не важно, со стороны сервера технология однотипная.
Если реальный интерес есть, то могу помочь с кодом.
---
CaptainMorgan,

Не стоит, я сделал проще.
Создал Web-сервис на стороне 1С.
Поднял Web-сервер appache.
Опубликовал Web-сервис.

По средствам Web-сервиса вызывается команда с параметрами (автомобиль, пробег, личный менеджер, дата записи).
1С-ка выполняет запрос за 2 сек. и выдает список интервалов по конкретному запросу пользователя. "Вуаля"
---
Вы пишите "Выполнение текста запроса ADODB.Connection командой ADODB.RecordSet"

Вопрос. Вы говорите про такой код?

```1c
    Connection = Новый COMОбъект("ADODB.Connection");
    Connection.Open("DRIVER=MySQL ODBC 3.51 Driver;Database=inventar_sm;DataSource=roman-book;UID=root;PWD=240580;STMT=set character_set_results=cp1251;");

    //Устанавливаем кодировку для нашего подключения (дополнительно)...
    Command= new COMObject("ADODB.Command");
    Command.CommandText = "set names cp1251";
    Command.ActiveConnection = Connection;
    Command.CommandType = 1;
    Command.Execute();

    //Теперь выполняем скрипт
    Command= new COMObject("ADODB.Command");
    Command.CommandText = "upd ate market_cards se t name='Мерседес' where articul='123'";
    Command.ActiveConnection = Connection;
    Command.CommandType = 1;
    Command.Execute();

    //Закрываем соединение.
    Connection.Close();
```

Есщё вы пишите: "Есть вариант создать таблицу в 1С, записывать данные в нее, а мобильное приложение по средствам подключения к базе данных MS SQL 1C будет вытягивать необходимые данные"

Скорее всего такой способ будет так же медленным.

Я бы предложил следующий подход.
Хранить данные на web-сервере. (Формат базы любой, хоть тот же MySQL)
А 1С, с определённой периодичностью, обращается к web-серверу по средствам post запроса и актуализирует данные.
Мобильное приложение, так же post-запросом получает актуальные данные с сервера и обновляет свою базу данных.

В этом способе все процедуры работы с базой будет выполнять web-сервер, а от 1С будет требоваться только единственное - сформировать post-запрос.
---
non1ka, почему не используете мобильное приложение от 1С? Достаточно обновить платформу до 8.3.7 или 8.3.8 и оставить режим совместимости. И все ваши пляски с бубном канут в лету.
---
я так понял вы всегда выполняете полную выгрузку расписания и соответственно замещение его в MySQL. А нельзя ли просто накапливать изменения от прошлой выгрузки и выгружать только их? мне кажется это уменьшит объем обмена данными в десятки раз => и затраты на обработку. Полную выгрузку тоже оставить и делать ее, например, сутра перед началом работы либо в ручном режиме в нештатных ситуациях. Но тогда еще нужно как-то получать ответ, что выгрузка принята, либо написать алгоритм выгрузки так, чтоб быть уверенным, что загрузка прошла и таблицу изменений можно очищать.
---
Забыл добавить вознаграждение :)
---
Есть методичка по мобильной платформе и есть видео курс на курсахпо1с.РФ
Пройдя курс все поймете. Неделя на обучение уйдет.
---
Задачи интеграции нужно решать не творчески, а согласно best practices.

1) Объемы результата запроса наводят на мысль, что в нем куча избыточных данных. Обрежьте период согласно требованиям бизнеса, а доступность менеджеров и подъемников разнесите по разным таблицам. Сделайте процесс выбора момента записи последовательным.
2) Конструктивно для интерграции с внешними системами предназначены веб и http - сервисы. В этом случае всю бизнес-логику можно будет реализовать на стороне 1С, что значительно гибче. Грубо говоря, вам нужно два метода:
а) По указанным дате и менеджеру получить график доступности
б) Занять поле графика доступности

3) Запрос на 190000 строк, выполняемый 53 секунды - это не кажется нормальным. Смотрите в план, скорее всего, у вас там либо скан, либо ошибка прогнозирования.
4) При преобразовании данных откажитесь от динамического кода, статический исполняется быстрее.
---
asved.ru,

2) Конструктивно для интерграции с внешними системами предназначены веб и http - сервисы. В этом случае всю бизнес-логику можно будет реализовать на стороне 1С, что значительно гибче. Грубо говоря, вам нужно два метода:

Да. согласен. Вникаю в Web-сервисы, и понимаю, что это единственно правильное решение.

3) Запрос на 190000 строк, выполняемый 53 секунды - это не кажется нормальным. Смотрите в план, скорее всего, у вас там либо скан, либо ошибка прогнозирования.

Запрос собирается из 50 временных таблиц, на несколько миллионов записей.
Это графики работы сотрудников, постов, занятые интервалы, нормы выполнения работ по автомобилям в разрезе пробега и т.д.
Результатом выполнения запросов являются 190 000 строк.

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

Спасибо за информацию. Код который представлен в теме, как раз написан для проверки скорости выполнения, первоначально был статический код :)

(9) sommid,

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

Да, действительно, это вариант решения. Мы его так же рассматриваем, но в настоящее время планируем реализовать взаимодействие по средствам Web-сервиса.

Спасибо огромное всем! Все советы очень полезные.

Мы сейчас попробуем реализовать интеграцию по средствам Web-сервиса.
О результатах напишу отдельно.

Отдельное спасибо - 4) CaptainMorgan, И (10) asved.ru,
&m - день переведу чуть позже. по результатам. может потребуются еще консультации :)
---
non1ka, так вы платформу уже обновили? На 8.2 их же нет кажись.
---
Xershi,
Есть. все ок.
---
Перевел &m (10) asved.ru,
Несмотря на то, что (15) CaptainMorgan, первым предложил решение, наиболее полное решение задачи все таки предложил (10) asved.ru.
Спасибо всем за помощь.
---
Напрашивается не "выгружать все возможные интервалы", а "выгружать изменения возможных интервалов".
То есть сделать регистр интервалов на стороне 1С, план обмена, и грузить изменения этого регистра.
---
Запрос собирается из 50 временных таблиц, на несколько миллионов записей.
Это графики работы сотрудников, постов, занятые интервалы, нормы выполнения работ по автомобилям в разрезе пробега и т.д.
Результатом выполнения запросов являются 190 000 строк.

И тем не менее, все же посмотрите в планы. Единственный неоптимизируемый запрос в 1С - это чтение объекта по ссылке :)