1C:TOP-100
КЛУБ ПРОФЕССИОНАЛОВ 1С
1C+SQL :: ToySQL :: FAQ
  Описание | Скачать | Заказать | Форум | FAQ | Клиенты | Партнеры | Разработки | Книга

08.06.2003 порог моего терпения был превышен. Стало очевидно, что необходим раздел, в который пользователь библиотеки должен обратиться в первую очередь. Убедившись на практике, что чтение документации для российского программиста "за падло", я решил, что это трехбуквенное сочетание на иностранном языке вызовет хоть какой позыв ткнуть в него мышкой, перед тем как задать какой-нибудь глупый вопрос. Итак, здесь вы можете получить ответы на вопросы, на которые я ни за что вам не отвечу по почте, на форуме, в аське или еще где-либо лично. Впрочем, ряд вопросов все же не столь очевиден и не описан в документации - в ответ на них я буду просто отсылать в этот раздел.

  • А почему не запускается библиотека (демо-версия)
    • Для успешного запуска демо-версии библиотеки необходимо выполнить следующие шаги:

      1. Скопировать лицензию в каталог вместе с библиотекой. При этом лицензия должна называться toysql21_d.lc. Иногда мне приходится отправлять сразу по несколько лицензий, поэтому необходимо добавлять к ним номер лицензии. Это удобно и вам - можно вспомнить какой номер заказа был вам присвоен.

      2. Зарегистрировать загрузчик (loader.dll) с помощью утилиты regsvr32.exe, которая обычно находится в системном каталоге вашей ОС. Под ОС типа NT это нужно делать, обладая правами администратора.

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

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

      Код лицензии ХХХХХХХХ - следующее сообщение, которое выдается всегда, если лицензия открыта. Если номер договора зарегистрирован верно, то этот код совпадает с тем, который использовал я при формировании лицензии.

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

      Количество объектов Х - последнее (обычно) сообщение, которое указывает на количество объектов, которые содержаться в лицензии. Это сообщение выдается просто для контроля.

      Ошибка загрузки объекта Х - последнее сообщение, которое может (хотя довольно редко выдаваться). Если оно выдается, то формат лицензии нарушен. Скорее всего это моя вина, либо старая версия библиотеки.

       
  • Почему вместо агрегатных объектов возвращаются коды
    • Скорее всего, вы работаете в монопольном режиме. Ведь так? По умолчанию в монопольном режиме свойство Вернуть1С (Return1C) имеет значение 0. Это значит, что возвращать нужно только коды объектов. Сделано это из-за того, что довольно часто в цикле программист пытается обратиться к свойствам объекта, который возвращается в наборе. При этом 1С инициирует еще один запрос к SQL Server, вследствие чего возникает конфликт - цикл выборки не закончен, а вы (т.е. 1С) пытаетесь создать еще одну выборку. Происходит крах системы. Чтобы избежать этого, но чтобы одновременно все же получить агрегатные объекты пользуйтесь выгрузкой результат набора в таблицу или список значений (метод Выгрузить). В этом случае набор закрывается по окончании выборки и потом можно обращаться к свойствам объектов без проблем.

      В разделенном режиме такая ситуация может случиться только если вы специально установили свойство Вернуть1С в 0.

  • Используйте в модуле проведения метод Соединиться(0)
    • Пока такого вопроса ко мне не поступало, но предвижу его появление. Если вы в модуле проведения попытаетесь обратиться к данным, которые заблокированы системой, то запрос завершится неудачей. Дело в том, что при проведении документа многие таблицы БД блокируются 1С и поэтому получить доступ к ним из другого соединения (что происходит по умолчанию в разделенном режиме) невозможно. Однако получить доступ к этим данным вы можете ч/з соединение 1С, то есть, используя метод Соединиться с параметром 0. Для этого лучше создавать отдельный объект ToyQuery.

      В монопольном режиме такой ситуации возникать не должно, так как работа происходит только ч/з соединение 1С.

  • Итоги по группировкам
    • Этот вопрос довольно часто задется мне. Специальной функции в библиотеке для этого нет. Но в T-SQL есть такая опция в предложении GROUP BY, которая позволяет получить итоги по всем группировкам перечисленным в этом предложении. Это опция называется WITH ROLLUP.

      Например, пусть такой запрос

      select field1, field2, SUM(field3) from table GROUP BY field1, field2

      возвращает такой набор данных:

      field1 field2 field3
      --------------------
      1 2 1
      1 1 2
      2 1 3
      2 2 4

      тогда запрос

      select field1, field2, SUM(field3) from table GROUP BY field1, field2 WITH ROLLUP

      вернет:

      field1 field2 field3
      --------------------
      1 2 1
      1 1 2
      1 NULL 3
      2 1 3
      2 2 4
      2 NULL 7
      NULL NULL 10

      Отличить строку группировки от обычной строки вы сможете с помощью свойства Пустое у объекта ToyField (поле).

  • Ускорение запроса по регистрам с использованием периода движения
    • Метазапрос по регистру с ипользованием периода движения работает относительно медленно. Это может проявится, например, при запросе по документам (особенно в этом случае). Дело в том, что в таком запросе рассчитываются остатки на каждый период движения, то есть на документ в нашем случае. Средствмами SQL это реализовано форированием временной таблицы, построением индекса по всем атрибутам группировки и соединением этой таблицы самой с собой. Это так называемый нарастающий итог. Так как документов за большой период может быть много - индекс строится долго и операция соединения тоже занимает время.

      В то же время запрос 1С по документам не рассчитывает остатки на документ. Эту ситуацию можете повторить и вы, разделив запрос на два запроса объединенных UNION ALL:

      QStr = "select [Рег.Номенклатура],[Рег.ПериодДвижения],[Рег.КонОстКол],[Рег.ПрихКол]
      |from
      |(
      |select [Номенклатура],ПериодДвижения = '' ,КонОстКол = [КонОст(Количество)],ПрихКол = 0
      |from [(Регистр.ОстаткиТМЦ([@НачДата],[@КонДата])
      |GROUP BY [Номенклатура])] РегОст
      |UNION ALL
      |select [Номенклатура],[ПериодДвижения],0,ПрихКол = [Приход(Количество)]
      |from [(Регистр.ОстаткиТМЦ([@НачДата],[@КонДата],[@""Документ""])
      |GROUP BY [Номенклатура],[ПериодДвижения])] РегДвиж
      |) Рег
      |order by [Рег.Номенклатура],[Рег.ПериодДвижения]";

      Такой запрос будет работать гораздо быстрее.

      p.s. Работа запроса возможна только начиная с версии 2.1.1.9 из-за ошибок в предыдущих версиях.

  • Суммирование обычных атрибутов
    • Функции Приход, Расход, Сумма предназначены только для использования в запросах по регистрам и бух итогам. Функция Сумма не используется для суммирования других числовых реквизитов. Для этого необходимо использовать стандартную агрегатную функцию языка SQL SUM: (SUM([СуммаДок])). Не забывайте заключать выражение в скобки, а также не забывайте о предложении GROUP BY, без которого агрегатные функции не могут использоваться.

  • Применение фильтров в запросах
    • Довольно часто возникает вопрос как с помощью фильтра производить отбор по реквизиту. Очень просто - необходимо лишь соеденить вашу таблицу с таблицей фильтра. Примерно так:

      SELECT [Спр.Владелец], [Спр.Ссылка], [Спр.Движение], [Спр.СчетД], [Спр.СчетК]
      |FROM [Справочник.ПроводкиХозОпераций] Спр,[ВремОбъекты.#Filter] Ф0
      |WHERE [Спр.СчетК] = [Ф0.Значение]
      |ORDER BY [Владелец],[Ссылка],[Движение]

  • Возможно ли реализовать опции предложения Группировать "Все" и "Все ВошедшиеВЗапрос" на ToySQL
  • Автоматическая установка библиотеки на большом количестве рабочих мест
    • Вы можете автоматизировать установку библиотеки на большом количестве рабочих мест добавив следующий код в предопределенную процедуру ПриНачалеРаботыСистемы:

      Процедура ПриНачалеРаботыСистемы()
      	Попытка 
      		Загрузчик = СоздатьОбъект("Toy.Loader");
      		Загрузчик.LoadLibrary(КаталогИБ()+"ToySQL21.dll");
      	Исключение
      		КаталогСистемы = ФС.WindowsКаталог()+"\system\";
      		ФС.КопироватьФайл(КаталогИБ()+"loader.dll",КаталогСистемы+"loader.dll",1);
      		ЗапуститьПриложение(КаталогСистемы + "regsvr32.exe /s " + "loader.dll");
      		Предупреждение("Необходимо перезапустить программу.");
      	КонецПопытки;
      КонецПроцедуры
       

      К сожалению данный метод применим только к системам типа Windows 95/98/Me, либо при работе в системах типа NT с правами администратора, либо если у пользователя имеются права на запись в некоторые разделы реестра.

  • Как получить остаток по регистру на точку актуальности
    • Для этого в качестве конечной даты используйте следующее выражение: КонМесяца(ПолучитьДатуТА()). В последних версиях библиотеки можно просто не указывать конечную дату и остаток будет считаться на точку актуальности

  • Использование функций SQL и выражений в запросах
    • Использование функций SQL и T-SQL ничем не ограничено. Единственное условие, которые вы должны соблюдать это заключение всякого выражения в списке SELECT в круглые скобки. В остальных предложениях операторов SQL этого делать не надо.

  • Ошибка 0x8007007e при регистрации loader.dll
    • Невероятно, что у вас появилась такая ошибка! В loader используются сторонние библиотеки по минимуму. После того как была убрана зависимость от atl.dll такой ошибки быть не должно. Если все же такая ошибка появилась, найдите в инете программку depends.exe (она идет вместе с Visual Studio) и посмотрите все зависимости. Если какой-то длл-ки не хватает, там сразу это станет видно. Иногда бывает, что зависимость от какой-либо библиотеки непрямая - то есть простой поиск по файлу библиотеки строк .dll может не помочь. Можете почитать (если сохранится на тот момент когда вы читаете) это обсуждение.

  • Метод Выгрузить для параметризованного запроса отрабатывает только один раз
    • В методе Выгрузить есть параметр, который отвечает за закрытие выборки. По умолчанию он равен 1, то есть после выгрузки в ТЗ выборка закрывается. В случае с параметризованным запросом этот параметр должен равнятся 0, чтобы выборка не закрывалась. В конце ее надо будет закрыть методом Close (Закрыть).

  • На одной машине ToySQL запускается на другой нет
    • Скорее всего не хватает какой-либо библиотеки необходимой для ToySQL. При этом в демо-версии вообще никаких сообщений не выдается, так как библиотека просто не может быть загружена. Обычно не хватает библиотеки msvcp60.dll. Какой библиотеки не хватает можно проверить с помощью программы из состава Visual Studio depends.exe ее можно найти в инете. Скопируйте библиотеки с той машины где библиотека работает на ту, где не работает.

  • Как получить остаток по регистру на документ
    • Ну как. Как обычно... :) Вместо даты нужно просто подставить документ. При этом если перменная документа создана ч/з СоздатьОбъект, то лучше передавать Док.ТекущийДокумент(). Для вычисления остатка в модуле документа используйте следующую конструкцию:

      SELECT [Партия],
      Кол = [НачОст(Количество)],
      Сум = [НачОст(Сумма)]
      FROM [(Регистр.Остатки([@ТекущийДокумент()])
      FROM [ТабличнаяЧасть.Перемещение] ТЧ
      WHERE [Фирма] = [@Фирма] AND
      [Склад] = [@Откуда] AND
      [ТЧ.Ссылка] = [@ТекущийДокумент()] AND
      [Рег.Товар] = [ТЧ.Товар]
      GROUP BY [Партия])] Рег
       

      в этом запросе главное, что нужно использовать функцию НачОст и указывать нужно только первую дату (документ). Фильтрацию по товарам можете делать по своему (ч/з СЗ, временный объект) - я делаю так. Да и не забывайте выполнить метод Соединиться(0), чтобы работать в соединении 1С.

  • В модуле проведения не подставляется ТекущийДокумент()
    • В модуле проведения желательно после каждого выполнения запроса вызывать метод Закрыть.

  • Виснет 1С при загрузке библиотеки. На некоторых компьютерах библиотека не загружается
    • Кроме проблем с необходимыми библиотеками, причиной (особенно в случае зависания 1С) могут быть старые драйвера клиентской части SQL Server (ODBC драйвера). Чтобы исключить эту возможную причину, скачайте с сайта Microsoft последний MDAC (Microsoft Data Access Components), в котором содержатся эти драйвера и установите его на тот компьютер, где библиотека не загружается.

      Причиной такого поведения библиотеки при загрузке может быть также использование вами в работе SQL Server Developer Edition. Уже в нескольких случаях я пытался установить ToySQL для работы в этой редакции, но либо новое соединение не создавалось, либо выполнение запроса тормозилось так, что казалось будто бы 1С зависла. Поэтому не рекомендую использовать в работе данную редакцию SQL Server. Хотя сам проверяю работу библиотеки именно на SQL Server Developer Edition.

      Проверить действительно ли проблема в драйверах (а точнее в SQL Server) вы можете загрузив 1С в монопольном режиме. При этом новое подключение не создается и работа производится ч/з соединение 1С.

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

  • Вылетает 1С в монопольном режиме при выборке данных
    • В монопольном режиме после выполнения запроса обязательно необходимо закрывать выборку методом Закрыть. Если во время выборки произошло исключение (ошибка и т.п.),то выборка остается открытой и когда 1С пытается выполнить свой запрос, то возникает ошибка. Рекомендую в монопольном режиме "проблемные" места заключать в конструкцию Попытка Исключение и при исключении закрывать выборку.

(с) Шемякин Павел aka toypaul , 2001 - 2004. веб-дизайн "абрис" & toypaul