Запустить от юзера агент-odbc должен быть на сервере

Тема в разделе "Lotus - Программирование", создана пользователем Karlosss, 9 апр 2010.

  1. Karlosss

    Karlosss Гость

    Все привет!
    Есть база на сервере, в базе есть форма документа с полями выбора условий для отчета. Юзер выбирает условия отбора, нажимает на кнопку для формирования отчета в excel.
    По кнопке запускается агент. Агент обращается по odbc к БД Оракл. Вопросы:
    1. Каким образом можно настроить агент или odbc, чтобы при работе он использовал odbc драйвер с сервера, а не локально?
    2. При работе агент спрашивает пароль для доступа к БД Оракл, хотя в скрипте имя и пароль посылаются на сервер. Как запомнить пароль чтобы он не спрашивал его постоянно?
     
  2. Xalet

    Xalet Well-Known Member

    Регистрация:
    8 авг 2008
    Сообщения:
    410
    Симпатии:
    0
    А вы уверены, что агент на сервере запускается, потому как, судя по вопросам, такое ощущение, что с клиентской машины.
     
  3. Karlosss

    Karlosss Гость

    Да , именно с клиентской машины. Вопрос как раз в том чтобы с клиентской машины запускался агент таким образом чтобы использовал odbc драйвер сервера.
     
  4. TIA

    TIA :-)
    Lotus team

    Регистрация:
    15 май 2009
    Сообщения:
    790
    Симпатии:
    0
    Запускать агента методом Agent.RunOnServer
     
  5. nvyush

    nvyush Lotus team
    Lotus team

    Регистрация:
    22 апр 2009
    Сообщения:
    2.317
    Симпатии:
    0
    По условию задачи
    пользователю нужно, чтобы агент исполнялся на клиенте. По крайней мере формировать отчёт в ёкселе на сервере проблематично, недавно обсуждалось.
     
  6. TIA

    TIA :-)
    Lotus team

    Регистрация:
    15 май 2009
    Сообщения:
    790
    Симпатии:
    0
    Да пусть запускается на клиенте, только ещё пинает RunOnServer. Серверный агент пусть выскребает данные из Оракла и складывает в документ. Клиентский агент пусть читает такой документ и формирует отчёт в Excel.
    Параметры для формирования условий отбора можно через тот же документ передавать.
     
  7. Karlosss

    Karlosss Гость


    Да , спасибо , идею я понял, буду пробовать.
     
  8. Karlosss

    Karlosss Гость

    Сделал следующую конструкцию:
    1. Текущий документ , в котором пользователь определяет критерии для отчета.
    2. Агент , который запускается на сервере , но толкается из текущего документа пользователем.

    Пользователь выбирает критерии поиска и клик на кнопку для создания отчета. Текущий док сохраняется, в нужное поле вставляется его id. Запускается агент на сервере. Выполняется запрос к базе оракл. Создается текстовый файл, куда записывается результат запроса. Файл вкладывается в документ , который находится в базе по id. Далее снова переходим на локальное выполнение кода. Находим док поиска по id , достаем из него результаты запроса в виде текст. файла и строим отчет.
    Это все вернее так должно было быть. Но не получается. Агента отдельно я дебажил и код на кнопке тоже . Может где то принципиально ошибся или просто описАлся. Проверьте плз.

    На кнопке:
    Код (LotusScript):
    Sub Click(Source As Button)
    Dim ws As New NotesUIWorkspace
    Dim session As New NotesSession
    Dim db As NotesDatabase
    Dim agent As NotesAgent
    Dim rtitem As NotesRichTextItem
    Dim object As NotesEmbeddedObject
    Dim EWindow As Variant
    Dim WorkBooks As Variant
    Dim WorkSheet As Variant

    Set db = session.CurrentDatabase
    Dim doc As NotesDocument
    Dim doc_temp As NotesDocument
    Dim uidoc As NotesUIDocument
    Set uidoc=ws.CurrentDocument
    Set doc= uidoc.Document
    Set view=db.GetView("Отчеты")
    myID=doc.NoteID
    doc.myID = doc.NoteID
    Call uidoc.save()
    Call uidoc.close(True)

    Call db.getAgent("odbc4").runOnServer(myID) ' Толкаем агента на сервере, передаем id документа для вставки вложения

    Set doc_temp=view.GetDocumentByKey(myID)

    Set rtitem = doc_temp.GetFirstItem( "Body" )
    Set object=rtitem.GetEmbeddedObject("otchet_suvd.txt")
    Call object.ExtractFile( "c:\Temp\otchet_suvd.txt" )' - достаем файл и строим по нему отчет

    i=2
    Print "Запуск Excel ..."
    Set EWindow = CreateObject("Excel.Application")'

    If EWindow Is Nothing Then
    Print "Excel не найден"
    End If

    Set WorkBooks=EWindow.Workbooks
    WorkBooks.Add
    EWindow.visible = True
    Set WorkSheet=EWindow.ActiveWorkBook.ActiveSheet
    WorkSheet.Cells(1,1).value = "ФИО"
    .....  
    Open "c:\Temp\otchet_suvd.txt" For Input As fileNum          
    Do While Not Eof(fileNum)
    Line Input #fileNum, st
    razbor=Split(st, ",")

    WorkSheet.Cells(i,1).value = razbor(0)
    WorkSheet.Cells(i,2).value = razbor(1)

    Loop   
    Close   #fileNum   
    End Sub
    Агент на сервере:
    Код (LotusScript):
    Sub Initialize
    Dim ws As New NotesUIWorkspace
    Dim db As NotesDatabase
    Dim session As New NotesSession
    Dim doc As NotesDocument
    Dim doc_otch As NotesDocument
    Dim view As NotesView
    Dim uidoc As NotesUIDocument
    Set db=session.CurrentDatabase
    '===== stream==================
    Dim stream As NotesStream
    Dim rtitem As NotesRichTextItem
    Dim object As NotesEmbeddedObject
    Dim item As NotesItem
    Dim pathname As String
    Dim stttr As Variant
    '=============================
    Dim con As New ODBCConnection
    Dim qry As New ODBCQuery
    Dim result As New ODBCResultSet

    '=========Подключение к ODBC================

    Call con.ConnectTo("ORACLE","имя","пароль") 'подключение к ODBC
    status = con.ConnectTo ("имя odbc")
    If Status = False Then
    Messagebox "Не могу подключиться к источнику данных ODBC: " + odb, 16, "Внимание !!!"
    Exit Sub
    End If

    Set qry = New ODBCQuery
    Set result = New ODBCResultSet
    Set qry.Connection = con
    Set result.Query = qry

    qry.SQL={запрос} ...

    If Not result.Execute Then
    Messagebox result.GetExtendedErrorMessage,,result.GetErrorMessage
    Call result.Close(DB_CLOSE)
    Call con.Disconnect
    Exit Sub
    End If

    '============Создание текстового файла=================================
    pathname="c:\Temp\otchet_suvd.txt" ' change location
    Set stream = session.CreateStream

    If Not stream.Open(pathname, "windows-1251") Then
    Messagebox pathname+" не найден",, "Open failed"
    Call stream.Close
    Exit Sub
    End If


    '=====================================================================
    result.cacheLimit =DB_ALL
    result.CacheLimit=DB_NONE
    'result.Execute
    If Not result.IsResultSetAvailable Then Exit Sub
    If result.FirstRow Then      
    Do
    ......................читаем результат запроса и складываем его в текст файл     

    stttr =result.GetValue("CONTACTS")+","+temp_fil & Chr(10)
    Call stream.WriteText(stttr)

    If result.IsEndOfData Then If result.IsEndOfData Then Exit Do
    result.NextRow
    Loop

    End If
    Call stream.Close
    Call result.Close(DB_CLOSE)
    Call con.Disconnect
    Set view = db.GetView("Отчеты")
    Set doc_otch=view.GetDocumentByKey(myID)
    Set rtitem = New NotesRichTextItem( doc_otch, "Body" )
    Set object = rtitem.EmbedObject(EMBED_ATTACHMENT, "", "c:\Temp\otchet_suvd.txt") ' вкладываем текст файл в документ поиска
    Call doc_otch.Save(True,True)
    End Sub
     
  9. TIA

    TIA :-)
    Lotus team

    Регистрация:
    15 май 2009
    Сообщения:
    790
    Симпатии:
    0
    0. Что конкретно не получается?
    1. Вставь option declare.
    2. Как в агенте получен myID
    3. Что будет, если пользователь повторно, из того же документа запустит поиск
     
  10. hosm

    hosm * so what *

    Регистрация:
    18 май 2009
    Сообщения:
    2.450
    Симпатии:
    7
    А это правильно, кстати? Вьюха подходит, мб, надо указать 2й параметр True?
     
  11. lmike

    lmike нет, пердело совершенство
    Команда форума Lotus team

    Регистрация:
    27 авг 2008
    Сообщения:
    6.073
    Симпатии:
    299
    особливо мне нра пассаж с временным файлом ;), в общем темпе...
    доступ у подписанта д.б. соответ, и у юзера от имени кот. запущают домину
    а потом с доступностью ОДБЦ и ёваного юзер систем сорцов, из-под доминошного юзера, тоже вопросы...
    а не прощели jdbc заюзать было (изначально)
    и из потока генерить документ с вложением (это хоть и не проще, но зато секурней и файло не надо на диске держать)
     
  12. Karlosss

    Karlosss Гость

    0:Насколько я понимаю, после операции Call db.getAgent("odbc4").runOnServer(myID) на сервере должен отработать агент и я должен получить object, при этом должна быть какая-то временная задержка пока агент отрабатывает , а на деле строка по быстрому пролетает и object пустой.
    1: В option- Uselsx "*LSXODBC" , в declare ничего нет.
    2. Вот как он получен хз, по идее строка Call db.getAgent("odbc4").runOnServer(myID) должна передать его агенту,но... дело для меня новое , есть подозрение , что делаю я что-то не так, вот и прошу совета , что я делаю не так?
    3. В данном случае пользователь тут я, на сервер win2003 залогинен я с правами админа, сервер запущен от меня, база подписана сервером. Запускать можно много раз , но ничего не меняется.

    Скорее всего я не правильно передаю myID агенту...


    Добавлено:
    Не очень понял , что здесь имелось ввиду? В принципе я дебажил и кнопку и агент отдельно , все отрабатывало, надо вот теперь как это все соединить...



    Добавлено:
    Делал как умел, можно так , можно по другому - не принципиально, цель пока заставить работать odbc сервера.
    Как я и писал уже , сервер запущен от меня. На java писать не умею, ведь jdbc использует java так ведь?
    Может быть я в общем не правильно собрал конструктор , подскажите как сделать лучше. Ведь то что я написал это не строго, предложения принимаются :O_0:
     
  13. nvyush

    nvyush Lotus team
    Lotus team

    Регистрация:
    22 апр 2009
    Сообщения:
    2.317
    Симпатии:
    0
    Имелось ввиду добавить в раздел Options строку Option Declare. Это заставляет компилятор проверить явное объявление всех переменных. Бережёт от ошибок типа неициализированных переменных и вообще полезно.

    Непонятно, а зачем собственно временный файл класть аттачем в рт-поле? Не проще в само рт-поле поместить нужную информацию?
     
  14. hosm

    hosm * so what *

    Регистрация:
    18 май 2009
    Сообщения:
    2.450
    Симпатии:
    7
    п.2. В агенте должно быть получение документа, переданного ему, примерно так
    Код (LotusScript):
    Dim s as new Notessession
    noteid = s.CurrentAgent.parameterdocid
    if noteid <> "" then
    Set doc = s.CurrentDatabase.GetDocumentByID(noteid) ' документ, переданный агенту
    end if
     
  15. hosm

    hosm * so what *

    Регистрация:
    18 май 2009
    Сообщения:
    2.450
    Симпатии:
    7
    проверь myID до этой команды:
    "В принципе я дебажил и кнопку и агент отдельно" - не на сервере ведь агент отлаживался, локально?
    А агент именно на сервере вообще запускается?
    Проверь Return value status = notesAgent.RunOnServer(...). Status of the operation where 0 indicates success.
    С ОДБС работает, результаты в файл записывает? Обрати внимание на сообщение lmike. Папка темповая там есть нужная?
    + при наличии прав можно пытаться почистить за собой файл с помощью команды kill имяфайла.
    попробуй просто поменять в агенте одно поле в переданном документе - например, заменить на тек.время и сохранить документ. Если так работает, значит, нормально с получением-передачей документов и просто запуском агента на сервере.
    Потом отладь работу с серверной БД, запись в файл. Возможно, надо повысить уровень безопасности агента - allow restricted operations.
    А потом и в документ запиши...
    зачем оба варианта сразу?
     
  16. TIA

    TIA :-)
    Lotus team

    Регистрация:
    15 май 2009
    Сообщения:
    790
    Симпатии:
    0
    Karlosss
    Смотри ещё лог сервера. Там наверняка есть сообщение об ошибке серверного агента, какой-нибудь Object variable not set.
    Для уточнения ошибочной операции, добавь обработчик ошибок с выводом Error$, Erl, GetThreadInfo(10)

    По поводу 2 го параметра GetDocumentByKey посмотри хелп.
     
  17. lmike

    lmike нет, пердело совершенство
    Команда форума Lotus team

    Регистрация:
    27 авг 2008
    Сообщения:
    6.073
    Симпатии:
    299
    Karlosss
    java - это не страшно, достаточно нагуглить готовые пример и вставить его в агент (на форуме они есть) и в серверном файловом пути домины (jvm/lib/ext) прописать оракловый файл с библиотекой... (.jar)
    нужен именно JDBC Thin, для оракла (чтобы не устанавливать полный клиент, а обойтись одним файлом)
    для отладки на клиенте - в аналогичное место положить библу
    общая инфа по ждбц http://www.wutka.com/hackingjava/ch15.htm
    оракловый вариант http://www.rgagnon.com/javadetails/java-0112.html

    по файловому пути - домина юзает \"свой\" темп, и его надо получить (источника не помню, приведу код):<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">код</div></div><div class="sp-body"><div class="sp-content">
    Код (LotusScript):
    \'Class_TempFolderManager:

    Const ERR_UNSUPPORTED_PLATFORM = 20300 \' arbitrary value
    Private agentLog As NotesLog
    Class TempFolderManager
    m_path As String
    m_files List As Integer

    Function Unique As String
    Dim unik
    unik = Evaluate(\"@Unique\")
    Unique = Strtoken(unik(0), \"-\", -1)   \' drop the username part of the ID which is always the same for this user
    End Function

    Sub New
    m_path = GetNotesTempDirectory & \"/\" & Unique
    Mkdir m_path
    End Sub

    Public Property Get Path As String
    Path = m_path
    End Property

    Function NewFilename(Byval strSuffix$, Byval bManage As Boolean) As String
    Dim strFName$
    strFName = Unique
    If strSuffix <> \"\" Then strFName = strFName & \".\" & strSuffix
    NewFilename = m_path & \"/\" & strFName
    If bManage Then
    m_files(NewFilename) = 0
    End If
    End Function

    Sub Manage(Byval strPath$)
    m_files(strPath) = 1
    End Sub

    Sub Unmanage(Byval strPath$)
    On Error Resume Next
    Erase m_files(strPath)
    End Sub

    Function ClearFiles( ) As Boolean
    \' erase all files under management but leave the directory so that we can use it more.
    \' return True if all files were successfully erased.
    On Error Goto failed
    ClearFiles = True
    Forall ffileno In m_files
    Kill Listtag(ffileno)
    nextFile:
    End Forall
    Erase m_files
    Exit Function
    failed:
    ClearFiles = False
    Resume nextFile
    End Function

    Sub Delete
    On Error Resume Next
    If ClearFiles Then Rmdir m_path
    End Sub
    End Class
    Declare Function w32_OSGetSystemTempDirectory Lib \"nnotes\" Alias \"OSGetSystemTempDirectory\" ( Byval S As String) As Integer
    Declare Function mac_OSGetSystemTempDirectory Lib \"NotesLib\" Alias \"OSGetSystemTempDirectory\" ( Byval S As String) As Integer
    Declare Function linux_OSGetSystemTempDirectory Lib \"libnotes.so\" Alias \"OSGetSystemTempDirectory\" ( Byval S As String) As Integer

    Function GetNotesTempDirectory() As String
    \' Returns the path of the temporary directory used by Notes.
    \' Not same as system or user temp dir that you can get e.g. with Environ(\"TEMP\") in Windows.
    \' Main reasons to use this instead: works crossplatform, and partitioned servers each need
    \' their own temp dir to avoid interfering with each other.
    Dim session As New NotesSession
    Dim d As String * 256
    Dim s%
    Select Case session.Platform
    Case \"Linux\"
    s% = linux_OSGetSystemTempDirectory(d)
    Case \"Macintosh\"
    s% = mac_OSGetSystemTempDirectory(d)
    Case \"Windows/32\"
    s% = w32_OSGetSystemTempDirectory(d)
    Case Else
    Error ERR_UNSUPPORTED_PLATFORM, \"In GetNotesTempDirectory, platform not supported: \" & session.Platform
    End Select
    GetNotesTempDirectory = Left$(d, s%)
    End Function
     
  18. nvyush

    nvyush Lotus team
    Lotus team

    Регистрация:
    22 апр 2009
    Сообщения:
    2.317
    Симпатии:
    0
    Модераторы, это нужно поместить codebase, однозначно.
     
  19. hosm

    hosm * so what *

    Регистрация:
    18 май 2009
    Сообщения:
    2.450
    Симпатии:
    7
    done. получение темпового пути Лотус кроссплатформенно
    Если еще посоветуете в личку, как назвать тему и описать по-русски правильно и поудобней (например, для удобства поиска), цены Вам не будет.
    что-то не никак складно не придумывается, сплю на ходу, так уж сегодня получилось...
    А если вместо мессаг "модераторы" вдруг сами запостите хорошее решение - смело заплюсую))) :(
    Почитайте "пользование кодебейз", там же написано всё )
    а то только 2-3 человека в КБ решения пишут, остальніе либо не знают, либо боятся ;)
     
Загрузка...

Поделиться этой страницей