I am creating a Lotus Notes application which has to have dynamic combo boxes. The choices for the combo boxes need to be retrieved by selecting from a SQL database.
I am new to Lotus Notes / Domino, I would love to know how to connect my SQL database for use in the domino designer. Thanks.
Edit: this is the client, not the web
Sub Initialize
On Error GoTo e
Dim pw As String,user As String,odbc As String
Dim i As Integer
Dim conn As ODBCConnection,query As ODBCQuery,rs As ODBCResultSet
Dim db As NotesDatabase
Dim session As NotesSession
Dim view As NotesView
Dim doc As NotesDocument
Dim newDoc As NotesDocument
Set session = New NotesSession
Set db = session.CurrentDatabase
Set view = db.GetView("Reports")
Set doc = view.GetFirstDocument
Set conn = New ODBCConnection
Set query = New ODBCQuery
Set rs = New ODBCResultSet
Set query.Connection = conn
Set rs.Query = query
odbc = "server"
user = "user"
pw = "pass"
Call conn.ConnectTo( odbc , user , pw )
i = 0
query.SQL = "SELECT * FROM table"
rs.Execute
rs.FirstRow
Do While Not rs.IsEndOfData
i = i + 1
rs.NextRow
Loop
conn.Disconnect
Exit Sub
e :
MessageBox "Error " & Err & " line " & Erl & ": " & _
Error
Exit Sub
End Sub
The questions is tagged Lotusscript so I assume that this is Lotusscript related (and not XPages related).
Have a look at the ODBCConnection, ODBCQuery, and ODBCResultSet Lotusscript classes in the Domino Designer Help database.
If you're not able to use any XPages components, you could try the ODBC variant of #DBLookup in the 'Use formula for choices' part of your combobox.
The code you have added to the question is going to cause an infinite loop due to the while/wend
Depending on how often the choices for the dropdown boxes change you could also create a scheduled agent that connections to the SQL server. I do this a lot for some of my own internal applications as it cuts down on unnecessary traffic to the SQL server if the values being returned are always the same.
Your scheduled agent would need to use the LSXLC extensions by adding UseLSX "*lsxlc" to the options section of the Lotusscript agent.
The LSXLC has a LOT of options which would be beyond the scope of this question so I would recommend looking at the Domino Designer Help files and searching for lsxlc. There are lots of examples in the help files.
Have a look at extlib on OpenNTF. It has an XPages component that allows you to connect to make SQL calls.
http://extlib.openntf.org
if you are using an xpages application, you can use a managed bean or static java method to get the data you want and bind it to the select values of the of combobox control.
Related
I am trying to change the links in an Access 2016 database, but the method I've used in the past is not working as required.
I am using the
t.connect="new connection"
t.refreshlink
method, where t is a the table.
I have seen in the linked table manager that the tables are now grouped by a data source. I can create the new source and link it to the desired table, but I have many as migrating, so would like to do this in code.
I get no errors the current way, but immediately after the .refreshlink the table's .connect is still the same.
Is this still possible?
I currently populate a dictionary with the table name and it's existing connection, but only if non ODBC.
I am then looping through this dictionary, getting the table and changing its connection
CurrentDb.TableDefs(strTableName).Connect = strNewConnection
CurrentDb.TableDefs(strTableName).RefreshLink
Debug.Print CurrentDb.TableDefs(strTableName).Connect
Existing connection = ;DATABASE=\\app01\Access\CRM_Data.mdb
New connection =;DATABASE=C:\CRM_TEST\CRM_DATA_BE_2016.accdb
Many thanks
You should not use CurrentDb.TableDefs when changing tables, as that changes between calls and makes the reference to the tabledef where you change the connection string be a different one than the one where you refresh the link.
Dim d As DAO.Database
Set d = CurrentDb
d.TableDefs(strTableName).Connect = strNewConnection
d.TableDefs(strTableName).RefreshLink
AFAIK this behaviour is not version-dependent, so the code you provided should never have worked.
I am using this code in Access 2016 and it works just fine:
Public Function RelinkTables(environment As Integer)
On Error Resume Next
Dim tblDef As DAO.TableDef
For Each tblDef In CurrentDb.TableDefs
If tblDef.Connect <> "" Then
tblDef.Connect = GetConnectionString(environment)
tblDef.RefreshLink
End If
Next
End Function
Public Function GetConnectionString(environment As Integer) As String
Select Case environment
Case 1 ' connection to Test db
GetConnectionString = "your connection string to Test"
Case 2 ' connection to Prod db
GetConnectionString = "your connection string to Production"
End Select
End Function
If this would not work with your db than may be the path is wrong.
I tried to run a SAS code through VBA. I'm running SAS on a server. I have a test SAS program "Program1.sas" which I've kept on the server. Below is the VBA code that I've used. The SAS code is running but the output dataset is just showing the column headers and the rows are empty.Can anyone help me what could be the possible reason.
Sub Form_Load23()
Dim obObjectFactory As New SASObjectManager.ObjectFactory
Dim obObjectKeeper As New SASObjectManager.ObjectKeeper
Dim obServer As New SASObjectManager.ServerDef
Dim obSAS As SAS.Workspace
Dim cn As New ADODB.Connection
Dim rs As New ADODB.Recordset
obServer.MachineDNSName = "xyz"
obServer.Protocol = SASObjectManager.Protocols.ProtocolBridge
obServer.Port = 8871
obObjectFactory.LogEnabled = True
Set obSAS = obObjectFactory.CreateObjectByServer("sas", True, obServer,"userid", "password")
obSAS.LanguageService.Submit ("options source2; %include '/abc/AFP/shikhar.gupta1/amg/**Program1.sas**';")
End Sub'
I believe you have to change the security settings in excel. Find the security settings and protected viewing. The remove all the check marks.
This is an issue on the SAS side. It can happen when your user does not have the metadata 'read' permission on the relevant dataset. It can also happen if your program has an error, and options obs=0; is set.
As #vasilij mentions, use proc printto to write your log to a file system and check for issues, also use SMC to check your metadata permissions.
Hi I don't have experience with VB6 or VB.NET but am trying to convert some old code to .NET. The VB6 uses PrivDBEngine.
Public oDbEngine As New PrivDBEngine
After some googling this looks like DAO. I was told to replace its usage with ADO.NET. I pasted every spot I see it in the code below as a reference in case it helps. I'll get to googling "PrivateDBEngine DAO to ADO.NET" but if anyone knows of an equivalent in ADO.NET or even has some useful links please let me know. Should I be looking into DataSet? Thank you very much for your time and patience. Other places I encounter it are:
' Build the proper connection string. If ODBC, the
' options line of the OpenDatabase method accepts the
' connection string. If Access, just pass in the
' filename
sPassword = Password
Select Case ConnType
Case DBTYPE_ACCESS
DBFilename = ConnectString
If (Len(UserName) = 0 And Len(Password) <> 0) Then
DBOptions = ";PWD=" + Password
sPassword = ""
Else
DBOptions = ""
End If
If (UserName = "") Then
UserName = "Admin"
Else
UserName = UserName
End If
If (Len(SystemMDB) <> 0) Then
---> oDbEngine.SystemDB = SystemMDB <-----------
End If
And also:
' Handle UserName and Password.
Set oWorkSpace = oDbEngine.CreateWorkspace("Test", UserName, sPassword)
And lastly:
Sub CleanUpDBConnection()
On Error Resume Next
' Close the recordsets
grsIndexTable.Close
grsDocTable.Close
' Close the database
If Connected Then
DBConnection.Close
Set DBConnection = Nothing
oWorkSpace.Close
Set oWorkSpace = Nothing
Set oDbEngine = Nothing
CurrentDTable = ""
CurrentITable = ""
Connected = False
End If
End Sub
PrivDBEngine is part of DAO. It's similar to DBEngine.
In an application, you may need to connect to multiple databases with different workgroup security connections. The PrivDBEngine lets you do that separate from DBEngine.
A common scenario is the main database (connected via DBEngine) which has data pointing to other databases, each with their own workgroup security settings. In that case, PrivDBEngine would be use to open those databases.
Off the top of my head, I can't remember if you can support 3 workgroup security settings at one time, but you can certainly reset the PrivDBEngine variable as needed without impacting all the recordsets already open using the DBEngine variable.
You should use the same ACE/DAO/DBEngine code in VB.NET if you are using Access databases. ADO can replace some ACE/DAO code, especially if you're using SQL Server and just retrieving data, but if you're using Access databases, ACE/DAO supports features that ADO doesn't.
I'm following code I found on another site. Here's the basics of my code:
Dim SQL As String
Dim connString As String
connString = "ODBC;DSN=DB01;UID=;PWD=;Database=MyDatabase"
SQL = "Select * from SomeTable"
With Worksheets("Received").QueryTables.Add(Connection:=connString, Destination:=Worksheets("Received").Range("A5"), SQL:=SQL)
.Refresh
End With
End Sub
The problem with doing this is every single time they hit the button assigned to this it creates a new connection and doesn't ever seem to drop it. I open the spreadsheet after testing and there are many versions of the connection listed under Connections.
Connection
Connection1
Connection2
I can't seem to find a way to close or delete the connections either. If I add ".delete" after ".Refresh" I get a 1004 error. This operation cannot be done because the data is refreshing in the background.
Any ideas how to close or delete the connection?
You might ask yourself why you're creating a QueryTable every time in your code. There are reasons to do it, but it usually isn't necessary.
QueryTables are more typically design-time objects. That is, you create your QueryTable once (through code or the UI) and the you Refresh the QueryTable to get updated data.
If you need to change the underlying SQL statement, you have some options. You could set up Parameters that prompt for a value or get it from a cell. Another option for changing the SQL is changing it in code for the existing QueryTable.
Sheet1.QueryTables(1).CommandText = "Select * FROM ...."
Sheet1.QueryTables(1).Refresh
You can select different columns or even different tables by changing CommandText. If it's a different database, you'll need a new connection, but that's pretty rare.
I know that doesn't answer your question directly, but I think determining whether you really need to add the QueryTable each time is the first step.
For more on Parameters, see http://dailydoseofexcel.com/archives/2004/12/13/parameters-in-excel-external-data-queries/ It's for 2003, so there are few inconsistencies with later versions. The basics are the same, you just may need to learn about the ListObject object if you're using 2007 or later.
I had the same issue. The previous answer while a definite step in the right direction is a PITA.
It did however allow me to refine my search and the winner is...
http://msdn.microsoft.com/en-us/library/bb213491(v=office.12).aspx
i.e. for your existing QueryTable Object just do this:
.MaintainConnection = False
Works ever so swell. No more Access DB lock file after the data is refreshed.
You should declare the connection as a separate object then you can close it once the database query is complete.
I don't have the VBA IDE in front of me, so excuse me if there are any inaccuracies, but it should point you in the right direction.
E.g.
Dim SQL As String
Dim con As connection
Set con = New connection
con.ConnectionString = "ODBC;DSN=DB01;UID=;PWD=;Database=MyDatabase"
Worksheets("Received").QueryTables.Add(Connection:=con, Destination:=Worksheets("Received").Range("A5"), SQL:=SQL).Refresh
con.close
set con = nothing
I've found that by default new connections created this way are called "Connection". What I am using is this snippet of code to remove the connection but retain the listobject.
Application.DisplayAlerts = False
ActiveWorkbook.Connections("Connection").Delete
Application.DisplayAlerts = True
It can easily be modified to remove the latest added connection (or if you keep track of the connections by their index).
Application.DisplayAlerts = False
ActiveWorkbook.Connections(ActiveWorkbook.Connections.Count).Delete
Application.DisplayAlerts = True
Instead of adding another query table with the add method, you can simply update the CommandText Property of the connection. However you have to be aware that there is a bug when updating the CommandText property of an ODBC connection. If you temporarily switch to an OLEDB connection, update your CommandText property and then switch back to ODBC it does not create the new connection. Don't ask me why... this just works for me.
Create a new module and insert the following code:
Option Explicit
Sub UpdateWorkbookConnection(WorkbookConnectionObject As WorkbookConnection, Optional ByVal CommandText As String = "", Optional ByVal ConnectionString As String = "")
With WorkbookConnectionObject
If .Type = xlConnectionTypeODBC Then
If CommandText = "" Then CommandText = .ODBCConnection.CommandText
If ConnectionString = "" Then ConnectionString = .ODBCConnection.Connection
.ODBCConnection.Connection = Replace(.ODBCConnection.Connection, "ODBC;", "OLEDB;", 1, 1, vbTextCompare)
ElseIf .Type = xlConnectionTypeOLEDB Then
If CommandText = "" Then CommandText = .OLEDBConnection.CommandText
If ConnectionString = "" Then ConnectionString = .OLEDBConnection.Connection
Else
MsgBox "Invalid connection object sent to UpdateWorkbookConnection function!", vbCritical, "Update Error"
Exit Sub
End If
If StrComp(.OLEDBConnection.CommandText, CommandText, vbTextCompare) <> 0 Then
.OLEDBConnection.CommandText = CommandText
End If
If StrComp(.OLEDBConnection.Connection, ConnectionString, vbTextCompare) <> 0 Then
.OLEDBConnection.Connection = ConnectionString
End If
.Refresh
End With
End Sub
This UpdateWorkbookConnection subroutine only works on updating OLEDB or ODBC connections. The connection does not necessarily have to be linked to a pivot table. It also fixes another problem and allows you to update the connection even if there are multiple pivot tables based on the same connection.
To initiate the update just call the function with the connection object and command text parameters like this:
UpdateWorkbookConnection ActiveWorkbook.Connections("Connection"), "exec sp_MyAwesomeProcedure"
You can optionally update the connection string as well.
If you want to delete if right after refresh you should do the refresh not in the background (using first parameter -> Refresh False) so that you have proper sequence of actions
Try setting the QueryTable.MaintainConnection property to False...
"Set MaintainConnection to True if the connection to the specified data source is to be maintained after the refresh and until the workbook is closed. The default value is True! And there doesn't seem to be a UI check box for this (Read/write Boolean)"
Still relevant years later...battling the same issue and this is the most helpful thread out there. My situation is a variant of the above and I will add my solution when I find it.
I am using an Access database for my data source and establish a querytable on a new sheet. I then add two more new sheets and try to establish a querytable using the same connection on each of them, but to a different Access table. The first querytable works just fine and I use .QueryTables(1).Delete and setting the querytable object to Nothing to make it disconnected.
However, the next sheet fails on establishing a new querytable using the same connection, which was not closed. I suspect (and will add the solution below) that I need to drop the connection before deleting the querytable. Rasmus' code above looks like the likely solution.
I have an Access frontend with a lot of tables linked through ODBC to a MySQL backend. I have a VB.net application that sometimes adds columns to the tables in the backend, and when that happens, I need to refresh the link to the table in the frontend from the VB.net app to show the new columns.
I'll consider just about any solution as long as it doesn't require restarting MySQL or Access, and will allow me to refresh only the links I need to refresh (which I know in advance) as there are hundreds of links and tables in the frontend.
This should get you started:
Dim Con As New ADODB.Connection
Dim Cat As New ADOX.Catalog
Dim tbl As New ADOX.Table
Con.Open(m_sAccessDbPath)
Cat.ActiveConnection = Con
' Name the new Table and set its ParentCatalog property
' to the open Catalog to allow access to the Properties
' collection.
tbl.Name = m_sAccessDbTableName
tbl.ParentCatalog = Cat
' Set the properties to create the link.
tbl.Properties("Jet OLEDB:Create Link").Value = True
tbl.Properties("Jet OLEDB:Link Provider String").Value = RemoteDbPath
tbl.Properties("Jet OLEDB:Remote Table Name").Value = RemoteTableName
' Append the table to the Tables collection.
Cat.Tables.Append(tbl)
Source: http://bytes.com/topic/visual-basic-net/answers/370859-create-linked-table-access