ошибка: FRM47337 Tree node label can not be null при выполнении скрипта DECLARE |
Oracle Forms и Excel
Чтение данных из Excel
Несмотря на то что в Oracle есть свой построитель отчетов, иногда возникает потребность в нерегламентированных отчетах, то есть в тех отчетах, которые были не предусмотрены в ходе проектирования системы. Существует необходимость в загрузке данных из различных внешних источников, что обусловлено многообразием форм представления и хранения данных. Каждая среда разработки предоставляет различные интерфейсы экспорта и импорта данных; Oracle Forms, в свою очередь, поддерживает достаточно много технологий для осуществления загрузки и выгрузки данных из внешних источников.
В этой главе мы рассмотрим возможные способы экспорта и импорта данных между приложениями Excel и Oracle Forms с помощью пакета . В конце главы будет приведен пример экспорта и импорта данных с помощью технологии .
Oracle Objects for OLE (OO4O)
Oracle Objects for OLE ( OO4O ) - это разработанный компанией Oracle набор СОМ-компонентов, совместимых с OLE Automation, который позволяет работать с Oracle из клиентских приложений с использованием скриптовых языков. Этот метод лучше подходит для работы с Oracle, чем Microsoft Open Database Connectivity (ODBC), к тому же OO4O предоставляют полную поддержку PL/SQL. Oracle Objects состоят из трех компонент:
- OLE 2.0 Automation (InProcess) Server - эта компонента предоставляет интерфейс OLE Automation для приложений, поддерживающих OLE automation scripting (например, Visual Basic).
- Oracle Data Control - управляющий элемент для Visual Basic.
- Two C++ Class Libraries - C-библиотеки для Microsoft Foundation Classes (MFC) и Borland (OWL).
Особенно хорошо то, что вы можете использовать OO4O из любых приложений MS Office, применяющих VB-подобный язык макросов.
Ниже приведен простой пример создания соединения с базой данных Oracle на Visual Basic:
Sub Form_Load () Dim OraSession As Object 'Declare variables as OLE Objects Dim OraDatabase As Object Dim OraDynaset As Object Set OraSession = CreateObject("OracleInProcServer.XOraSession") Set OraDatabase = OraSession.DbOpenDatabase("SQL*Net_Connect_ String", "scott/tiger", 0&) MsgBox "Connected to " & OraDatabase.Connect & "@" & OraDatabase.DatabaseName 'Create the OraDynaset Object and display the first value Set OraDynaset = OraDatabase.DbCreateDynaset("select empno, ename from emp", 0&) MsgBox "Employee " & OraDynaset.Fields("empno").value & ", #" & OraDynaset.Fields("ename").value End Sub
Технология OO40 имеет солидное преимущество над другим подходом - VB/JET/ODBC:
- Доступ к данным осуществляется через идентификатор строки - rowid, а не через первичный ключ или уникальный индекс в подходе VB/ODBC. Если rowid доступен, то данные доступны для корректировки.
- Возможность создавать связываемые переменных в SQL-предложениях (т. е. " SELECT * FROM EMP WHERE ENAME = :name "). PL/SQL также поддерживает связывание переменных.
Пакет TEXT_IO
Пакет TEXT_IO в Oracle Forms обеспечивает доступ к файлам операционной системы.
Пакет TEXT_IO позволяет приложению, разработанному на Oracle Forms, как читать из файлов операционной системы, так и писать в них.
Возможность использовать пакет Text_IO появилась в Oracle Developer 2000 (Forms 4.5). Рассмотрим пример выгрузки данных с помощью набора процедур и функций пакета TEXT_IO:
declare out_file Text_IO.File_Type; flnm varchar2(200); begin flnm := GET_FILE_NAME ('H:\', 'file_name.xls', 'XLS Files (*.xls)|*.xls|', NULL, SAVE_FILE, TRUE); out_file:=Text_IO.Fopen (flnm, 'w'); LOOP Text_IO.New_Line (out_file); Text_IO.Put (out_file, :eid); Text_IO.Put (out_file, CHR(9)); Text_IO.Put (out_file, :NM); IF :system.last_record = 'TRUE' THEN EXIT; ELSE next_record; END IF; Text_IO.Fclose (out_file); end;
В этом разделе мы рассмотрели и проработали возможные варианты работы с Excel-файлами. Такое количество подходов дает вам возможность выбрать для себя наиболее удобный способ импорта и экспорта данных. Мы же с вами рассмотрим пример с использованием технологии .
Object Linking and Embedding
Мы уже изучали подробно эту технологию, когда применяли OLE-контейнер в нашем приложении. Сейчас же мы рассмотрим несколько иной вариант, а именно - встроенный пакет , который поддерживается во всех последних версиях Forms. Пакет сопровождает PL/SQL API для создания, манипулирования и доступа к атрибутам пакета .
Запуск и установка соединения с EXCEL
Для того чтобы манипулировать объектами , необходимо использовать определенный тип данных, который предназначен исклю-
чительно для работы с пакетом OLE2. В листинге 11.1 в секции DECLARE показан пример объявления переменных пакета.
DECLARE App ole2.obj_type; Book ole2.obj_type; Cell ole2.obj_type; Args ole2.list_type; … <другие переменные> … BEGIN Null; END;Листинг 11.1 . Объявление типов данных OLE2
Для вызова методов пакета нужно указывать ключевое слово - ole2.[метод, тип]. Показанный в примере тип данных ole2.obj_type служит для объявления объектов OLE2, а ole2.list_type используется для объявления списка аргументов. Если провести аналогию, то тип данных ole2.list_type очень похож на тип данных ParamList, который также содержит список параметров.
Следующим нашим шагом в изучении пакета OLE2 будет создание объектов OLE2 (листинг 11.2).
DECLARE App ole2.obj_type; BEGIN App:=OLE2.Create_Obj('Excel.Application'); END;Листинг 11.2 . Создание объекта OLE2
Для того чтобы проверить вышеописанный код, создайте произвольную форму с одной кнопкой. Создайте для кнопки обработчик WHEN-BUTTON-PRESSED и выполните в нем приведенный код. Когда в режиме выполнения формы вы нажмете на кнопку, ничего не произойдет, но это на первый взгляд, на самом же деле если вы откроете "Диспетчер задач", то увидите процесс EXCEL.EXE. Теперь, для того чтобы увидеть электронную таблицу в рабочей области, а не в диспетчере задач, добавьте в тело триггера код, приведенный в листинге 11.3, который не только отображает приложение EXCEL, но и загружает указанный файл.
DECLARE App ole2.obj_type; Book ole2.obj_type; DocName varchar2(100); WorkbooksCollection ole2.obj_type; Sheets ole2.obj_type; Sheet ole2.obj_type; args ole2.list_type; BEGIN docname:=GET_FILE_NAME(''); App:=OLE2.Create_Obj('Excel.Application'); OLE2.Set_Property(App,'VISIBLE', 1 ); WorkbooksCollection:=OLE2.GET_OBJ_PROPERTY(App, 'Workbooks' ); args:=OLE2.CREATE_ARGLIST; OLE2.ADD_ARG(args, docname); Book:=OLE2.Invoke_Obj(WorkbooksCollection,'Open', args); OLE2.DESTROY_ARGLIST(args); END;Листинг 11.3 . Запуск и отображение объекта OLE2
Для того чтобы вам было легко разобраться с примерами, которые будут приведены далее, ознакомьтесь с синтаксисом некоторых методов пакета (табл. 11.1).
- OLE2.Add_Arg - добавляет аргумент в список аргументов.
- OLE2.Add_Arg_Obj - добавляет объект-аргумент в список аргументов.
- OLE2.Create_arglist - создает список аргументов, который может быть передан OLE2.
- OLE2.Create_Obj - создает объект OLE2 Automation, например, Microsoft Word, Microsoft Excel.
- OLE2.Destroy_Arglist - уничтожает список аргументов.
- OLE2.Get_Char_Property - возвращает свойство объекта OLE2 Automation.
- OLE2.Get_Num_Property - возвращает идентификатор значения объекта OLE2 Automation.
- OLE2.Get_Obj_Property - возвращает значение объектного типа объекта OLE2 Automation.
- OLE2.Invoke - выполняет метод OLE2.
- OLE2.Invoke_Num - возвращает числовое (number) значение объекта OLE2 Automation, используя указанный метод.
- OLE2.Invoke_Char - возвращает символьное (character) значение объекта OLE2 Automation, используя указанный метод.
- OLE2.Invoke_Obj - возвращает значение типа объекта OLE2.
- OLE2.IsSupported - возвращает TRUE, если OLE2 поддерживается на текущей платформе.
- OLE2.Last_Exception - возвращает идентификатор последнего возбужденного исключения.
- OLE2.Release_Obj - сигнализирует объекту OLE2 Automation, что PL/SQL-клиент больше не нуждается в нем.
- OLE2.Set_Property - устанавливает значение указанного свойства объекта OLE2 Automation.
В листинге 11.3 для отображения приложения EXCEL на экране применяется процедура OLE2.SET_PROPERTY. В этом примере мы также использовали тип данных ole2.list_type для создания списка аргументов. Для того чтобы загрузить в EXCEL нужный нам файл, мы добавили аргумент docname, в который сохраняли имя запускаемого файла, а затем активировали его с помощью параметра " Open " процедуры Invoke_obj.