Как решить проблему с получением дробных чисел из MySQL в 1С 7.7

Программист 1С v7.7 Управленческий учет Торговля и дистрибуция
← На главную

При интеграции 1С:Предприятия 7.7 с внешними базами данных (например, MySQL, PostgreSQL или MS SQL) через механизм ADO (ActiveX Data Objects) разработчики часто сталкиваются со специфической ошибкой: "Тип переменной не поддерживается". Эта ситуация возникает в тот момент, когда код пытается обратиться к значению поля, имеющему в базе данных тип DECIMAL или FLOAT. Давайте подробно разберем, почему это происходит и как правильно обработать такие данные, чтобы они корректно попадали в документы и отчеты 1С.

Выясним причину возникновения ошибки

Проанализируем техническую сторону вопроса. Платформа 1С 7.7 была разработана в эпоху, когда стандарты COM/OLE имели определенные ограничения. Когда мы используем объект ADODB.Recordset, драйвер базы данных пытается передать значение поля в 1С в виде структуры Variant. Для полей типа DECIMAL современные драйверы используют подтип VT_DECIMAL или VT_CY.

Проблема заключается в том, что ядро 1С 7.7 не умеет "на лету" преобразовывать VT_DECIMAL во внутренний числовой формат 1С. Ошибка происходит не в момент присваивания значения переменной, а в момент обращения к свойству Value объекта Field. Именно поэтому стандартная функция Число() не помогает — программа "падает" еще до того, как данные попадают в функцию.

Рассмотрим также типичную синтаксическую ошибку, которую часто допускают начинающие разработчики:


// Ошибочный вариант
ТекТЗ.Сумма = Число("НаборЗаписей.Fields(2).Value");

В данном случае 1С пытается преобразовать в число саму текстовую строку "НаборЗаписей.Fields(2).Value", а не значение, которое лежит в базе данных. Правильное обращение к объекту должно быть без кавычек, но, как мы выяснили выше, для типа DECIMAL в 7.7 это все равно вызовет ошибку несовместимости типов.

Решение проблемы на стороне SQL-запроса

Самый эффективный и быстрый способ решить задачу — заставить сервер базы данных самостоятельно преобразовать число в формат, понятный для 1С. Разберем, как это сделать с помощью функции CAST или CONVERT прямо в тексте запроса. Посмотрим на практический пример.

Допустим, наш исходный запрос выглядит так:

ТекстЗапроса = "SELECT price, quantity FROM orders";

Чтобы 1С 7.7 смогла прочитать цену, мы преобразуем ее в строковый тип CHAR на стороне сервера. Проанализируем измененный код:


ТекстЗапроса = "SELECT 
               | CAST(price AS CHAR) as summa_str, 
               | quantity 
               | FROM orders";

Теперь в наборе записей поле summa_str будет содержать обычную строку (например, "1000.50"). 1С 7.7 прекрасно работает со строками, и мы можем легко превратить их в число уже внутри цикла обхода записей. Рассмотрим, как это выглядит в коде 1С:


Пока НаборЗаписей.Eof() = 0 Цикл
    ТекТЗ.НоваяСтрока();
    // Получаем значение как строку и преобразуем в число 1С
    СтроковоеЗначение = НаборЗаписей.Fields("summa_str").Value;
    ТекТЗ.Сумма = Число(СтроковоеЗначение);
    
    ТекТЗ.Кво = НаборЗаписей.Fields("quantity").Value;
    НаборЗаписей.MoveNext();
КонецЦикла;

Альтернативные методы обработки данных

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

1. Использование арифметических операций в SQL.

Иногда драйверы ODBC/OLEDB ведут себя иначе, если результат поля является продуктом вычисления. Попробуйте умножить значение на единицу с плавающей точкой. В некоторых случаях это принудительно меняет тип возвращаемого значения с DECIMAL на DOUBLE, который 1С 7.7 понимает лучше:

ТекстЗапроса = "SELECT (price * 1.0) as summa FROM orders";

2. Настройка драйвера MySQL (DSN).

Если вы используете подключение через System DSN, обратите внимание на настройки драйвера MySQL Connector/ODBC. Во вкладке "Cursors/Results" часто присутствует флажок "Treat DECIMAL as CHAR". Если его включить, драйвер будет автоматически передавать все поля DECIMAL как строки, и вам не придется менять текст SQL-запросов во всей конфигурации.

3. Обработка пустых значений (NULL).

Важно помнить, что если в поле базы данных содержится NULL, обращение к .Value в 1С 7.7 также может вызвать ошибку. Рекомендуем всегда использовать защитные функции на стороне SQL, такие как COALESCE или IFNULL. Разберем пример:

ТекстЗапроса = "SELECT CAST(IFNULL(price, 0) AS CHAR) as summa FROM orders";

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

Работа с внешними компонентами

Для профессиональной и стабильной работы с внешними источниками данных в среде 1С 7.7 мы рекомендуем использовать внешнюю компоненту 1С++. В ней реализован класс ODBCRecordset, который работает с базами данных напрямую через API, минуя ограничения ADO. Проанализируем преимущества этого метода:

Подводя итог, можно сказать: если вы столкнулись с ошибкой типа данных в 1С 7.7 при работе с MySQL, самым простым "лечением" будет использование CAST(поле AS CHAR) в вашем SQL-запросе. Это проверенный временем метод, который позволяет обойти ограничения старой платформы и обеспечить надежный обмен данными с современными веб-сайтами.

← На главную