Autor Thema: Probleme bei AS400 Abfrage mittels ODBC auf Domino-Server (RunOnServer)  (Gelesen 10230 mal)

Offline Basti07

  • Frischling
  • *
  • Beiträge: 19
Tag zusammen,

vielleicht könnt Ihr mir bei meinem Problem helfen.
Derzeit arbeite ich an einem Kundendienstformular. Hierüber sollen Reklamationen unserer Kunden abgewickelt werden. Unsere Mitarbeiter sollen im Formular u.a. Angaben zum Kunden - den es ja schon bei uns im System AS400 gibt - angeben. Es wäre also praktisch, wenn Daten wie Adresse, Telefonnummer, etc. nach Eingabe einer Kunden- oder Auftragsnummer automatisch per ODBC und SQL-Abfrage zur AS400 ermittelt werden und in das Formular eingesetzt werden.

Es funktioniert bereits, so lange der Agent und das konfigurierte ODBC direkt auf dem Client ausgeführt wird.
Das ist aber nicht Sinn der Sache, wir möchten dass der Agent auf dem Domino-Server ausgeführt wird. Entsprechend haben wir den Agenten umgebaut und verwenden den Befehl "Agent.RunOnServer".

Und jetzt zum Problem:
Leider werden die Abfrage-Ergebnisse des SQL-Statements nicht an den Client und in das Formular zurückgeschrieben, sondern nur in das Domino-Log des Servers (so wird es u.a. ja auch in der Designer-Hilfe beschrieben: "The user cannot interact directly with a called agent. User output goes to the Domino log.") Das ist natürlich blöd, denn an der Stelle bringt es uns ja recht wenig.

Gibt es einen Trick oder eine Alternative das SQL-Result an das Formular zu übergeben?
Leider bin ich nirgends fündig geworden.

Vielen Dank
Gruß Basti
« Letzte Änderung: 30.01.12 - 18:49:00 von Basti07 »

Offline m3

  • Freund des Hauses!
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 8.102
  • Geschlecht: Männlich
  • Non ex transverso sed deorsum!
    • leyrers online pamphlet
Schreib das Ergebnis in das Notes-Dokument, speichere es und refreshe im Anschluss das Display.
HTH
m³ aka. Martin -- leyrers online pamphlet | LEYON - All things Lotus (IBM Collaborations Solutions)

All programs evolve until they can send email.
Except Microsoft Exchange.
    - Memorable Quotes from Alt.Sysadmin.Recovery

"Lotus Notes ist wie ein Badezimmer, geht ohne Kacheln, aber nicht so gut." -- Peter Klett

"If there isn't at least a handful of solutions for any given problem, it isn't IBM"™ - @notessensai

Offline koehlerbv

  • Moderator
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 20.460
  • Geschlecht: Männlich
Ich würde eher nach der Fertigmeldung des NotesAgent.RunOnServer ein NotesUIDocument.Reload im Frontend durchführen. Ggf. ist auch noch ein folgendes NotesUIWorkspace.ViewRefresh erforderlich.

Bernhard

Offline m3

  • Freund des Hauses!
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 8.102
  • Geschlecht: Männlich
  • Non ex transverso sed deorsum!
    • leyrers online pamphlet
Das meinte ich ja ;)

BTW - Salzburg waere super! :D
HTH
m³ aka. Martin -- leyrers online pamphlet | LEYON - All things Lotus (IBM Collaborations Solutions)

All programs evolve until they can send email.
Except Microsoft Exchange.
    - Memorable Quotes from Alt.Sysadmin.Recovery

"Lotus Notes ist wie ein Badezimmer, geht ohne Kacheln, aber nicht so gut." -- Peter Klett

"If there isn't at least a handful of solutions for any given problem, it isn't IBM"™ - @notessensai

Offline koehlerbv

  • Moderator
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 20.460
  • Geschlecht: Männlich
BTW - Salzburg waere super! :D

Das finde ich auch, Martin. Absolut!  ;D

Bernhard

Offline Basti07

  • Frischling
  • *
  • Beiträge: 19
Danke Euch für den Tip, aber ich werde nicht ganz schlau wie ich das richtig anstellen soll.
Anbei mal der Code den ich aktuell für den Aufruf verwende und die Ausgabe im Domino-Log erfolgt.
Anstelle dieser Ausgabe soll alles (was unten im Code auskommentiert ist) an das derzeit geöffnete Dokument übergeben werden.
Ich bekomm's aber nicht gebacken, dem Agenten das aktuelle Dokument zu übermitteln.

Hier mal ein Teil des Codes:

Die Schaltfläche in dem Formular:

Code
Sub Click(Source As Button)
	Dim workspace As New notesuiworkspace
	Dim s As New NotesSession
	Dim db As NotesDatabase
	Dim doc As notesdocument
	Dim uidoc As notesuidocument
	
	Set uidoc = workspace.CurrentDocument
	Set doc = uidoc.Document
	Call uidoc.Save
	Dim agent As NotesAgent
	Set db = s.CurrentDatabase
	Set Agent = db.GetAgent("MeinAgent")
	Call Agent.RunOnServer()
	Call uidoc.Reload
	Call workspace.ViewRefresh
End Sub


Der Agent der per RunOnServer ausgeführt wird:

Code
Sub Initialize
	
	Dim con As ODBCConnection
	Dim dataSource As String
	Dim userName As String
	Dim password As String
	Dim qry As New ODBCQuery
	Set con = New ODBCConnection
	Dim result As New ODBCResultSet

	con.SilentMode = True
	
	dataSource = "AS400"
	userName   = "Username"
	password    = "Passwort"
	
	If Not con.ConnectTo(dataSource, userName, password) Then
		'Call uidoc.FieldSetText("Status", "Verbindungsfehler")
		MsgBox "Verbindungsfehler"
		con.Disconnect
		Exit Sub
	End If

	Set qry.Connection = con
	Set result.Query = qry

	qry.SQL ="SELECT Feld1, Feld2 FROM Tabelle1 WHERE Feld1 = 'Feld2'"

	result.Execute
	
	Error01 = "Result:"
	Error02 = result.GetErrorMessage(result.Execute)
	Error03 = result.GetExtendedErrorMessage(result.Execute)

	'Call uidoc.FieldSetText("Status", Error01 & Chr(10) & Error02  & Chr(10) & Error03)
	MsgBox "Error01 & Chr(10) & Error02 & Chr(10) & Error03

	Do
		result.NextRow
		
		If Not result.IsResultSetAvailable Then
			'Call uidoc.FieldSetText("Status", "Abfragefehler oder leeres Ergebnis!")
			MsgBox "Abfragefehler oder leeres Ergebnis"
			con.Disconnect
			Exit Sub
		End If

		Feld1 = result.GetValue("Feld1")
		Feld2 = result.GetValue("Feld2")

	Loop Until result.IsEndOfData

	'Call uidoc.FieldSetText("Formularfeld1", Feld1)
	'Call uidoc.FieldSetText("Formularfeld2", Feld2)
	MsgBox Feld1
	MsgBox Feld2
	con.Disconnect

End Sub

Offline koehlerbv

  • Moderator
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 20.460
  • Geschlecht: Männlich
Warum übergibst Du dem Agent nicht die NoteID des betreffenden Dokuments?
Warum dealst Du auf einem serverbasierenden Agent mit Messagebox und wunderst Dich, dass das Zeug im Server-Log landet?

Empfehlung: R.T.F.M.!

Bernhard

Offline Peter Klett

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 2.713
  • Geschlecht: Männlich
In Deinem auskommentierten Script arbeitest Du im Frontend (uidoc), das kann kein periodisch laufender Agent (agent.RunOnServer ist ein periodischer Agent).

Du musst

Dein geöffnetes Dokument speichern (falls es das noch nicht ist)
Den Agenten auf dem Server starten und dabei das Dokument mitgeben (NoteID)
Das Dokument durch den Agenten im Backend (also NotesDocument, nicht NotesUIDocument) mit Daten befüllen
Das geöffnete Dokument aktualisieren

Auch eventuelle Fehlermeldungen solltest Du in ein entsprechendes Feld im Dokument eintragen, dann kann der Benutzer die nach Lauf des Agenten direkt sehen.

Offline Basti07

  • Frischling
  • *
  • Beiträge: 19
Das mit der NoteID hat funktioniert und ebenfalls auch das Befüllen des Backend-Dokumentes, danke dafür!

Jetzt hebt's nur noch an dem NotesUIDocument.Reload / NotesUIWorkspace.ViewRefresh.
Das Frontend-Dokument wird und wird nämlich - trotz der o.s. Befehle nicht aktualisiert. Erst wenn ich das Frontend-Dokument schließe und wieder öffne, kann ich die neuen Werte sehen, aber ich will natürlich dass die Werte für den Anwender sofort zu sehen sind.

Gruß
Basti

Offline Peter Klett

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 2.713
  • Geschlecht: Männlich
Mit dem Reload habe ich keine Erfahrung. Wenn es wirklich nicht ohne Schließen und Öffnen geht, würde ich das halt tun (natürlich automatisch), da flackert nur mal kurz der Schirm. Einziger sonstiger Nachteil: Bei großen Dokumenten, bei denen der Benutzer vielleicht einen Reiter geöffnet hat oder nach unten gescrollt hatte, springt das Dokument natürlich auf den Anfang zurück.

Aber vielleicht kennt jemand einen Trick, wie man ein Dokument, das im Backend von einem Agenten verändert wurde, aktualisieren kann, ohne es zu schließen. Ich erinnere mich nicht, sowas jemals gebaut zu haben.

Offline koehlerbv

  • Moderator
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 20.460
  • Geschlecht: Männlich
NotesUIDocument.Reload + .ViewRefresh - solange da kein Richtext Item involviert ist (auch wenn es gar nicht geändert wurde).
Sonst hilft nur ein Close / Reopen, wie Peter es schon aufgemalt hat.

Bernhard

Offline Basti07

  • Frischling
  • *
  • Beiträge: 19
Ein RTI ist nicht vorhanden, habe mich nun aber trotzdem für das Close und Reopen-Verfahren entschieden und als Vorlage den Code von ata verwendet.

Was könnte das Problem sein, wenn trotz dem Reopen, die Felder nach wie vor leer bleiben und ich sie erst sehe wenn ich händisch schließe und wieder öffne??

Zum Ablauf:
In dem Button Click-Event rufe ich nach
Code
Call Agent.RunOnServer(doc.NoteID)
die u.s. ReOpen-Function mit
Code
Call ReOpen(doc)
auf.

Die ReOpen-Function habe ich etwas angepasst, da das
Code
doc.Save(True, True)
mir immer die zuvor vom Agent eingetragenen Werte rausschmeißt. In auskommentierter Form bleiben sie erhalten.

So ganz verstehen tu ichs nicht  ???
Habt Ihr noch eine Idee warum das ReOpen nicht funzt wie es soll?

Danke
Gruß Basti


Code
Function ReOpen(doc As NotesDocument) As Integer 
	Dim ws As New NotesUIWorkspace 
	Dim uidoc As NotesUIDocument 
	Dim dbThis As NotesDatabase 
	Dim unid As String 
	
	ReOpen = 0 
	Set dbThis = doc.ParentDatabase 
	'Call doc.Save(True , True)
	unid = doc.UniversalID
	doc.SaveOptions = "0" ' # ... Speicherabfrage vermeiden 
	Set uidoc = ws.CurrentDocument 
	Call uidoc.Close
	Set doc = dbThis.GetDocumentByUNID(unid) 
	Set uidoc = ws.EditDocument(True , doc)
	Set doc = uidoc.Document 
	If doc.HasItem("SaveOptions") Then 
            ' # ... das Feld SaveOptions wieder entfernen... 
		doc.RemoveItem("SaveOptions") 
		'Call doc.Save( True , True )
	End If 
	ReOpen = 1
	Print "Das Dokument wurde erneut geöffnet: " & unid
End Function

Offline Peter Klett

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 2.713
  • Geschlecht: Männlich
M.E. wird das Dokument nicht sauber geschlossen, sonst wäre die Abfrage nach dem SaveOptions nach dem Öffnen sinnfrei.

Dokument Speichern
SaveOptions setzen
UIDoc schließen

Wenn dieses Dokument wieder neu geöffnet wird, kann es kein SaveOptions haben, denn das kann nicht gespeichert worden sein. Ist es dennoch enthalten, ist es nicht wirklich völlig neu geladen worden.

Ich würde das Dokument nach dem Schließen aus dem Speicher entfernen und erst dann wieder öffnen.

Function ReOpen(doc As NotesDocument) As Integer
   Dim ws As New NotesUIWorkspace
   Dim uidoc As NotesUIDocument
   Dim dbThis As NotesDatabase
   Dim unid As String
   
   ReOpen = 0
   Set dbThis = doc.ParentDatabase
   'Call doc.Save(True , True)
    unid = doc.UniversalID
    doc.SaveOptions = "0" ' # ... Speicherabfrage vermeiden
   Set uidoc = ws.CurrentDocument
   Call uidoc.Close
   Delete doc
    Set doc = dbThis.GetDocumentByUNID(unid)
   Set uidoc = ws.EditDocument(True , doc)
    Set doc = uidoc.Document
   If doc.HasItem("SaveOptions") Then
            ' # ... das Feld SaveOptions wieder entfernen...
      doc.RemoveItem("SaveOptions")
      'Call doc.Save( True , True )
    End If

    ReOpen = 1
    Print "Das Dokument wurde erneut geöffnet: " & unid
End Function

Offline Basti07

  • Frischling
  • *
  • Beiträge: 19
Peter, das Delete hat's gebracht!

Vielen Dank

 

Impressum Atnotes.de  -  Powered by Syslords Solutions  -  Datenschutz