Object variable not set в примере из мануала

Автор newby, 23 августа 2023, 18:57

0 Пользователи и 1 гость просматривают эту тему.

newby

Здравствуйте всем. Новичок. Пытаюсь понять что не так с элементарным примером. Пример из мануала:

Sub aQueryContent
 Dim oDatabaseFile As Object
 Dim oQuery As Object
 Dim stQuery As String
 oDatabaseFile = ThisComponent.Parent.CurrentController.DataSource
 oQuery = oDatabaseFile.getQueryDefinitions()
 stQuery = oQuery.getByName("Query").Command
 MsgBox stQuery
End Sub

DB подключена.
Все переменные объявлены.
Исполнение кода выдает ошибку Object variable not set на первом же вхождении имени объявленной  переменной, как на картинке. Это касается на самом деле всех переменных в приведенном примере и не только в нем.
В чем дело? Мануалом нельзя пользоваться? Нужно загрузить, включить какие-то библиотеки?
Некоторые примеры работают исправно, но все, что связано с подключением к DB - везде выдает именно такую ошибку.
Кто-нибудь встречался/разбирался с подобным?
Заранее благодарен за разъяснение.

Матчасть: Windows 10, LibreOffice 7.5, Мануал Base Guide 7.3, lLEBRE_OFFICE_BASE_BG73-BaseGuide.pdf, стр. 462

mikekaganski

Как написано в мануале,

ЦитироватьHere the content of a *.odb file is accessed from a form.

Вы выполняете этот код из формы?
С уважением,
Михаил Каганский

sokol92

Лучше использовать в подобных случаях ThisDatabaseDocument.
Владимир.

sokol92

Мне кажется, имена переменных Basic выбраны не совсем удачно и могут вводить в заблуждение. Попробуйте так - можно макрос запускать из формы (встроенного текстового документа) или непосредственно из объекта базы данных.
Sub aQueryContent2()
 Dim oDataSource As Object
 Dim oQueries As Object
 Dim stQuery As String
 oDataSource = ThisDatabaseDocument.DataSource
 oQueries = oDataSource.getQueryDefinitions()
 stQuery = oQueries.getByName("Query").Command
 MsgBox stQuery
End Sub
Владимир.

newby

Цитата: mikekaganski от 23 августа 2023, 19:23Как написано в мануале,

ЦитироватьHere the content of a *.odb file is accessed from a form.

Вы выполняете этот код из формы?
Спасибо за подсказку. Вы правы, исполнять код нужно исключительно привязанным как макрос в кнопке на форме.

newby

Цитата: sokol92 от 23 августа 2023, 22:33Мне кажется, имена переменных Basic выбраны не совсем удачно и могут вводить в заблуждение. Попробуйте так - можно макрос запускать из формы (встроенного текстового документа) или непосредственно из объекта базы данных.
Sub aQueryContent2()
 Dim oDataSource As Object
 Dim oQueries As Object
 Dim stQuery As String
 oDataSource = ThisDatabaseDocument.DataSource
 oQueries = oDataSource.getQueryDefinitions()
 stQuery = oQueries.getByName("Query").Command
 MsgBox stQuery
End Sub

Спасибо, вы правы, исполнять надо из объекта формы. Увы

newby

Цитата: sokol92 от 23 августа 2023, 21:51Лучше использовать в подобных случаях ThisDatabaseDocument.
Спасибо за полезняшку, почитаю.

newby

Спасибо всем откликнувшимся!
Вопрос снят. Код исполняется только из формы БД.
Похоже и в остальных случаях, которые пробовал, ситуация та же - код исполнялся из ненадлежащего приложения.

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

Предполагал, что в БД сделаю разные нужные Query на Таблицы БД, подпишу на них диапазоны таблицы Calc через drag-and-drop и, с помощью макросов из таблицы Calc, буду менять критерии в Query, обновляя макросами в Calc соответсвующие диапазоны.

Видимо не судьба... все ж попробую поискать решение, может и получится.

Всем еще раз спасибо.

sokol92

#8
Цитата: newby от 24 августа 2023, 13:16Это печально, получается, что объектная модель зависит от приложения.
LibreOffice - единое приложение (в отличие от Microsoft Office).
Есть прекрасная книга А.Питоньяка по написанию программ для Base: AndrewBase.odt (сейчас с сайтом Питоньяка проблемы).
Ваш пример можно переписать так, чтобы он работал из любого места. Нужно только указать полный путь к odb - файлу (или имя зарегистрированной базы данных).
Sub aQueryContent3()
 Dim oDataSource As Object, oDataBaseContext As Object
 Dim oQueries As Object
 Dim stQuery As String
 oDataBaseContext = CreateUnoService("com.sun.star.sdb.DatabaseContext")
 oDataSource=oDataBaseContext.getByName(ConvertToUrl("C:\Temp\FormFocus4.odb"))
 oQueries = oDataSource.getQueryDefinitions()
 stQuery = oQueries.getByName("Query").Command
 MsgBox stQuery
End Sub

Также макросами можно создавать и обновлять диапазоны данных (DatabaseRange), связанные с запросами (Query). Код макросов для этих действий достаточно компактный.
Владимир.

newby

Цитата: sokol92 от 24 августа 2023, 16:04
Цитата: newby от 24 августа 2023, 13:16Это печально, получается, что объектная модель зависит от приложения.
LibreOffice - единое приложение (в отличие от Microsoft Office).
Есть прекрасная книга А.Питоньяка по написанию программ для Base: AndrewBase.odt (сейчас с сайтом Питоньяка проблемы).
Ваш пример можно переписать так, чтобы он работал из любого места. Нужно только указать полный путь к odb - файлу (или имя зарегистрированной базы данных).
Sub aQueryContent3()
 Dim oDataSource As Object, oDataBaseContext As Object
 Dim oQueries As Object
 Dim stQuery As String
 oDataBaseContext = CreateUnoService("com.sun.star.sdb.DatabaseContext")
 oDataSource=oDataBaseContext.getByName(ConvertToUrl("C:\Temp\FormFocus4.odb"))
 oQueries = oDataSource.getQueryDefinitions()
 stQuery = oQueries.getByName("Query").Command
 MsgBox stQuery
End Sub

Также макросами можно создавать и обновлять диапазоны данных (DatabaseRange), связанные с запросами (Query). Код макросов для этих действий достаточно компактный.

Увы, не все так просто, как выяснилось. Но решаемо. Спасибо за подсказку.

economist

Не все просто c Base, а что-то прям сложно, если не знать. С SQL-запросами в Basic есть пара занятных фишек, способных вычеркнуть пару дней из жизни:

1) нужно помнить про почти обязательный .EscapeProcessing = False, но иногда его нужно включать (параметрические запросы с [?] и некоторые случаи при работе с Формами БД)

2) иногда приходится кодом создавать именованный запрос в ODB, потому что только ему можно гарантированно установить/сбросить флаг парсера EscapeProcessing, прямая передача аргументом есть, но не срабатывает (баги описаны, когда-то исправят).

В целом LO Base кмк самый недооцененный (и при этом самый перспективный и конкурентный) продукт. Активность в ветке Base https://forumooo.ru/index.php?board=9.0 прямо скажем, не блещет. Но это не проблема продукта, а проблема ленивых пользователей и IT-шников. Активнее нам надо, товарищи!

Вот все эти импортозамесы-конкуренты P7/Only/Мой/Alter итд красиво обтекают тему БД, типа не наше, используйте СПО/1С. Но фишка баз данных - в доступности их внутри контекста Текста/Таблицы, по нажатию Ctrl+Shift+F4 В этом Либра сильна и может не стыдиться своих мелких глюков.

Насчет организации Запросов-хранимок. У Питоньяка есть код чтения/записи их в odb, сами их можно собирать налету прямо в Calc и доверить это юзерам. Это проще чем выучить DAX/M у конкурента, а главное что SQL наконец-то пошел в массы, причем откуда не ждали, от "сотен тысяч закончивших курсы" и просто на хайпе DS. Мне это нравится, у обычных офисных людей, студентов, домохозяек из вершков теории реляции появляется системное видение многих вещей. Так, глядишь, через пяток лет перестанем жить чужим мнением и начнет проверять стат-гипотезы через p-value, так же часто, как репостим мемасы. То есть все станем учеными ;) 

Но интерфейс Base в части "хранимок" - неудобен, нет иерархии SQL-запросов, нет поиска, ранжирования, категоризации, метрик скорости выполнения итд. Поэтому люди чаще работают с odb-файлами не из Base, а из Calc/Writer. Рисуем там "формы ввода" и получаем офис-морду (док-морду) к БД, удобную и настраиваемую. А если нужна web-морда к данным - ныряем во встроенный в LO Python, в его простые фреймворки Streamlit, Flask, FastAPI итд. И получаем полное покрытие технологий стеком свободных инструментов, которые даже не нужно устанавливать (просто скачать настроенный portable).
Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...