Показаны сообщения с ярлыком OEBS. Показать все сообщения
Показаны сообщения с ярлыком OEBS. Показать все сообщения

13.10.2014

OeBS: Обновление параметра FND_INIT_SQL на уровне полномочий

Параметр содержит анонимный блок, выполняющийся при инициализации полномочий. Ниже - пример кода изменения значения параметра для группы полномочий.

23.04.2014

Загрузка и распарсивание файла xls с помощью Java-based concurrent

Цель: прочитать файл электронной таблицы Excel 95-2003 и загрузить результат в таблицу БД Oracle 11g. В нашем примере мы хотим прочитать данные из одной ячейки и положить их в таблицу create table HF_TMP (val VARCHAR2(50))
Алгоритм решения:
1. Загрузка файла через пользовательский интерфейс. Применяется messageFileUploadBean с типом данных BLOB. 

При нажатии кнопки Загрузить происходит вставка записи в таблицу загрузок вместе с бинарным файлов Excel в blob-поле, присваивание upload_id и запуск Java-based канкарента, в который этот upload_id передается.
CO:
Serializable[] aserializable = { uploadId };
Class[] aclass = { uploadId.getClass() };
String requestId = (String)am.invokeMethod("sendConcurrentRequest", aserializable, aclass);
am.getTransaction().commit();
AM:
public void sendConcurrentRequest(Number uploadId) throws RequestSubmissionException {
  ConcurrentRequest cpRequest = new ConcurrentRequest(this.getOADBTransaction().getJdbcConnection());
  Vector requestParameters = new Vector(1);
  requestParameters.add(uploadId.stringValue());
  int requestId = cpRequest.submitRequest(UploadHistFactBean.APPLICATION_SHORT_NAME, UploadHistFactBean.CONCURRENT_PROGRAM_NAME, null, null, false, requestParameters);
}
2. Работа канкарента
    // считываем BLOB
    public InputStream getFileForUploadId(){
        StringBuffer strBuf = new StringBuffer();
        InputStream dataStream = null;
        String lQuery = "select file_data from DATA_UPLOADS where request_id = :1";
        String res = "";
        try
        {
          OracleCallableStatement statement = (OracleCallableStatement)connection.prepareCall(lQuery);
          statement.setInt(1, requestId);
          ResultSet resultSet = statement.executeQuery();
          while (resultSet.next()) {                  
              BLOB blob = ((OracleResultSet)resultSet).getBLOB(1);
              dataStream = blob.getBinaryStream();
          }       
        } catch (SQLException e)
        {
          throw OAException.wrapperException(e);
        }
        return dataStream;
    }
    public void initialize(CpContext cpContext) throws SQLException,
                                                       XMLParseException,
                                                       SAXException,
                                                       IOException,
                                                       InstantiationException,
                                                       IllegalAccessException,
                                                       ClassNotFoundException,
                                                       NoSuchMethodException,
                                                       InvocationTargetException     {
        connection = cpContext.getJDBCConnection();
        requestId = cpContext.getReqDetails().getRequestId();
        logFile = cpContext.getLogFile();
        reqCompletion = cpContext.getReqCompletion();
        NameValueType parameter;
        while (cpParameters.hasMoreElements()) {
         parameter = cpParameters.nextParameter();
          if ("p_upload_id".equalsIgnoreCase(parametr.getName())) {
          this.uploadId = Integer.valueOf(parametr.getValue()).intValue();
        }
    }
    public void runProgram(CpContext cpContext) {
        try {
            initialize(cpContext);
            HashMap<String, String> inputParameters = new HashMap<String, String>();
            inputParameters.put(DataInput.PARAMETER_PREFIX + "1",                                   "oracle.apps.xxmy.test.bean.TemplateXML");
            InputStream file = getFileForUploadId();

            { логика по распарсиванию файла Excel }
            connection.commit();

            // Успешно завершим конкаррент
            Message normComplMessage = new Message("FND", "CONC-CP SUCCESSFUL TERMINATION");
            reqCompletion.setCompletion(ReqCompletion.NORMAL, normComplMessage.getMessageText(cpContext.getResourceStore()));
        } catch (Exception e) {
            // Если произошла ошибка, нужно выставить конкаренту ошибочный статус и выдать в лог стек ошибки
            reqCompletion.setCompletion(ReqCompletion.ERROR, e.getMessage());
            StringWriter errStringWriter = new StringWriter();
            PrintWriter errPrintWriter = new PrintWriter(errStringWriter, true);
            e.printStackTrace(errPrintWriter);
            logFile.writeln(errStringWriter.toString(), LogFile.ERROR);
        } finally {
            cpContext.releaseJDBCConnection();
        }
    }
3. Распарсивание XLS с помощью библиотеки POI. Шаблон oracle.apps.xxmy.test.bean.TemplateXML из шага 2 содержит набор параметров для вызова API вставки в таблицу с указанием данных о том, в каких ячейках брать значения. В нашем случае:
<?xml version="1.0" encoding='windows-1251'?>
<upload method="XXMY_TEST_PKG.upload_excel">
 <element name="test" type="single">
  <location src="sheet" sheet="Sheet1" row="0" col="0"/>
 </element>
</upload>
Пробегаясь по структуре данных и файлу данных, мы формируем вызов API:
begin XXMY_TEST_PKG.upload_excel(P_TEST => :1, P_REQUEST_ID => :2, P_UPLOAD_ID => :3, P_UPLOAD_METHOD => :4); end;
Имея коллекции параметров и их значений, выполняем вызов:
    public void doDbUpload() throws SQLException {
        OracleCallableStatement statement = (OracleCallableStatement)connection.prepareCall(this.query);
        ArrayList<Integer> keyList = new ArrayList<Integer>();
        keyList.addAll(uploadParameters.keySet());
        Collections.sort(keyList);
        Iterator<Integer> parameterIterator = keyList.iterator();
        while (parameterIterator.hasNext()) {
            Integer parameterIndex = parameterIterator.next();
            UploadParameter parameter = this.uploadParameters.get(parameterIndex);
            statement.setString(parameterIndex.intValue(), parameter.getValue());
        }
        statement.execute();
        statement.close();
    }
Всё. Данные из файла отправляются в таблицу.

18.02.2014

WebADI: правка LDT вручную

Функционал интегратора OeBS, прямо скажем, не совершенен.
Глюки, с которыми сталкивался я:
  • быстрее и проще создать интегратор с нуля, чем править уже имеющийся. При удалении объектов интегратора не удаляются внутренние связи, и если удалить, например, один контент и создать новый под другим именем, мэппинг будет упорно ссылаться на старый;
  • если в интеграторе нет ошибок, это ещё не значит, что он будет корректно выполнять свою задачу. Это касается, например, добавления новых колонок в шаблон и интерфейсную таблицу. Колонки созданы, изменения в интерфейсе, мэппинге и контенте проведены, шаблон выгружается и загружается нормально, но данные просто не попадают в таблицу. Никаких ошибок, никакого результата;
  • при создании разметки полей документа двигать их по одному, пока не добьешься нужного порядка - занятие неэффективное, но другого инструмента BNE не предоставляет. Почему бы не выводить окошко с номером сразу для всех колонок? Здесь глюк был в том, что если спускать колонку сверху вниз, то на середине пути она замирает и не реагирует на нажатия кнопок "вверх", "вниз".
Итак, когда у нас есть большой и сложный интегратор, а нам нужно туда добавить несколько колонок, можно поправить LDT вручную. Программа действий:
1. Добавление атрибутов в интерфейс
BEGIN BNE_INTERFACE_COLS "2" //увеличивать это число
      OWNER = "ANONYMOUS"
      OBJECT_VERSION_NUMBER = "2"
      INTERFACE_COL_TYPE = "1"
      INTERFACE_COL_NAME = "LOAD_CODE"
      ENABLED_FLAG = "Y"
      REQUIRED_FLAG = "N"
      DISPLAY_FLAG = "Y"
      READ_ONLY_FLAG = "N"
      NOT_NULL_FLAG = "N"
      SUMMARY_FLAG = "N"
      MAPPING_ENABLED_FLAG = "Y"
      DATA_TYPE = "1"
      FIELD_SIZE = "22"
      DEFAULT_TYPE = "PARAMETER"
      DEFAULT_VALUE = "XXIP361_CODE"
      VAL_COMPONENT = "" ""
      DISPLAY_ORDER = "2" //увеличивать это число
      PROMPT_LEFT = "Код загрузки"
      PROMPT_ABOVE = "LOAD_CODE"
      LAST_UPDATE_DATE = "2013/05/24"
      VAL_QUERY = "" ""
      EXPANDED_SQL = "" ""
    END BNE_INTERFACE_COLS 
2. Добавление атрибутов в контент
BEGIN BNE_CONTENT_COLS "3" //увеличивать это число
      OBJECT_VERSION_NUMBER = "1"
      OWNER = "ANONYMOUS"
      COL_NAME = "PROJECT_CODE"
      USER_NAME = "PROJECT_CODE"
      LAST_UPDATE_DATE = "2013/05/24"
      READ_ONLY_FLAG = "N"
    END BNE_CONTENT_COLS
3. Правка таблицы BNE_STORED_SQL. Запрос апдейтим напрямую, добавив новые поля интерфейсной таблицы.
4. Добавление атрибутов в мэппинг BNE_MAPPING_LINES (внимательно!)
BEGIN BNE_MAPPING_LINES "2"  //увеличиваем это число
      INTERFACE_ASN = "XXMY"
      INTERFACE_CODE = "XXMY_LOAD_X_INTF1"
      INTERFACE_SEQ_NUM = "12"  //ID атрибута интерфейса
      OWNER = "ANONYMOUS"
      DECODE_FLAG = "N"
      OBJECT_VERSION_NUMBER = "1"
      CONTENT_ASN = "XXRT"
      CONTENT_CODE = "XXMY_LOAD_CNT2"
      CONTENT_SEQ_NUM = "2"    //ID атрибута контента
      LAST_UPDATE_DATE = "2013/05/24"
    END BNE_MAPPING_LINES
5. Добавление атрибутов в LAYOUT (внимательно!)
BEGIN BNE_LAYOUT_COLS "520"  //увеличиваем число с шагом в 10
        OWNER = "APANIN"
        OBJECT_VERSION_NUMBER = "1"
        INTERFACE_ASN = "XXMY"
        INTERFACE_CODE = "XXMY_LOAD_X_INTF1"
        INTERFACE_SEQ_NUM = "45" //ID атрибута интерфейса
        DISPLAY_WIDTH = "15"
        LAST_UPDATE_DATE = "2014/02/13"
        READ_ONLY_FLAG = "N"
      END BNE_LAYOUT_COLS
После этих манипуляций интегратор должен работать с новыми колонками.
Порядок столбцов в формируемом документе excel можно узнать запросом:
with col_order as
 (select intr.interface_col_name, col.sequence_num
    from BNE_LAYOUTS_B        lay,
         BNE_LAYOUT_BLOCKS_B  blo,
         BNE_LAYOUT_COLS      col,
         BNE_INTERFACE_COLS_B intr
   where lay.layout_code = blo.layout_code
     and blo.layout_code = col.layout_code
     and blo.block_id = col.block_id
     and intr.sequence_num = col.interface_seq_num
     and intr.interface_code = 'XXMY_LOAD_X_INTF1'
     and lay.layout_code = 'XXMY_CORRECT_LOAD'
     and blo.block_id = 2  //номер блока (1 - шапка документа)
   order by col.sequence_num)
select co.interface_col_name, co.sequence_num from col_order co;
Для изменения порядка делаем апдейт таблицы BNE_LAYOUT_COLS.

14.01.2014

Описательные гибкие поля (DF) и OAF

Descriptive Flex Fields (описательные ГП) - инструмент в среде OeBS для универсализации использования одних и тех же полей таблиц для хранения свойств разных сущностей. Обычно это набор полей ATTRIBUTE1..ATTRIBUTE15 varchar2(150) для хранения свойств и поле ATTRIBUTE_CATEGORY для хранения контекста. В зависимости от контекста одно и то же поле может иметь разный бизнес-смысл.

10.04.2013

OAF: Реализация механизма связывания страниц train

Последовательность действий для реализации train

26.03.2013

OAF: Атрибут VO как хинт к бину image

Возникла задача присвоить значкам типа image различные всплывающие подсказки из ViewObject. Один из вариантов реализации  - через JavaScript.

11.03.2013

Использование JavaScript в OAF

Примеры использования JS в Oracle Applications Framework. Вызов JAVA-методов из кода JavaScript

14.02.2013

Динамическое условие required в параметре канкарента

Если выбрали А = 1, то должны заполнить параметр B,
Если выбрали А != 1, то параметр В должен быть неактивен.

13.02.2013

XML Publisher: кое-что о больших отчетах

Почему стоит отказаться от гигантских отчетов.

06.02.2013

Трассировка concurrent-процесса

Получение трассы с последующим чтением с помощью TKPROF

17.01.2013

Адресация на элементы дерева hGrid

Построить дерево hGrid с определенного элемента можно с помощью метода OAHGridBean.setInitialFocusPath(intArr), где intArr - массив элементов типа int. Как его, массив, формировать?

30.11.2012

PL/SQL Entity Object

Создание Enitiy Object c переопределенной логикой операций DML. Подход обычно применяется в случае наличия API для таблицы.

25.10.2012

WF: Валидация параметров

API процедур PL/SQL, ассоциированных с функциями процесса Workflow, предусматривают несколько режимов работы (параметр funcmode)

08.08.2012

WF: Бизнес-событие и подписка на основе потока

Выполнения workflow-потока, инициируемого бизнес-событием

26.06.2012

Oracle XML Publisher: простейший отчет в Excel

Компания Oracle не поддерживает надстройку по созданию Publisher отчетов для MS Excel. Для создания отчета нужно применить некоторые другие средства.

25.06.2012

Oracle XML Publisher: простейший отчет в RTF

Процесс создания отчета состоит из этапов: создание Шаблона определения данных (Data Definition), создание RTF шаблона представления данных конечному пользователю, создание Параллельного (concurrent) приложения, добавление созданного приложения в группу запросов пользователя, выполнение отчета с параметрами.