How can I connect to Lotus thru ODBC using VBA? - vba

I'm interested in setting up an Access db to run a report automatically. To save myself the trouble of going to each client computer and setting up the appropriate DSNs, I'd like to set up the ODBC connections in the VB script itself if possible.
I've googled and checked this site and found some good starter code, but not enough to make all the error messages go away. Can someone complete the code below?
Sub SetupODBC(Str_Server as string, Str_Db as string)
'Str_Server=Name of Server
'Str_db=Name of Database
Dim C as ADODB.Connection
Set C = new ADODB.Connection
C.ConnectionString = ??
C.Open
Debug.print C.State
Exit Sub

Welcome to the board. ConnectionStrings is indeed your friend, but the issue you are having is that you don't have the driver:) Lotus Notes is not a relational database it is a document oriented database. Historically there has not been a way to Access it like it is a relational database for that reason. However IBM eventually got around to writing a sort of translator in the form of NotesSQL. If you follow the link and get the driver you should be able to use ODBC. It is worth noting that Notes exposes itself to COM. So if push comes to shove you can automate the client.

This site is your friend: http://www.connectionstrings.com/access
I didn't follow your question correctly at first. I see you want to create a link from Access to Lotus to report on Lotus Notes data. Well there are a few ways to do so.
I frequently use a method of exposing Lotus Notes data as XML, then accessing that XML from the remote system. You can easily create a Notes Page with the XML start tag, root element, and then insert an embedded view in between the root element. That embedded view then needs to display as HTML and contain columns that resolve to xml tags. For instance, each row of the view would look similar to this:
<Person><FirstName>Ken</FirstName><LastName>Pespisa</LastName></Person>
and your column formulas would be:
"<Person><FirstName>" + FirstName + "</FirstName>"
for the first name column, and for the last name column it would be this:
"<LastName> + LastName + </LastName></Person>"
Note that this assumes that your Notes server has the HTTP service turned on and you can reach the database via a browser.
However as mentioned by other answers, you can use other methods such as NotesSQL and COM. It sounds like you are putting this solution on many workstations, though, and NotesSQL would require you to install the driver on each workstation. The COM method would work without requiring any extra work at the users' desks so I'd favor that solution in this case.

Looks like a great site for my needs, even if it hasn't been updated in a year. But still no cigar. Now, I'm getting "Data source name not found and default driver not specified"
(Obviously, ServerNameGoesHere and DatabaseNameGoesHere are subsitutions)
Sub dbX()
Dim C As adodb.Connection
Set C = New adodb.Connection
C.Open _
"Driver={Lotus NotesSQL 3.01 (32-bit) ODBC DRIVER (*.nsf)};" & _
" Server=ServerNameGoesHere;" & _
" Database=DatabaseNameGoesHere.nsf;"
C.Close
End Sub

Related

Connection template, resetting connections and looping thru

Back Story
I am working with SAGE Mas 200 software, trying to link to it through Access. This software houses date for 300 investors for my company. With EACH investor I have a different investor ID that goes along with my UID and Password upon logging in, therefore EVERY connection string is different.
After many hours of trial and error, I have been successful in connecting via Access to only find out that I can only have one active connection string per database. Since I have 300 investors that I need to pull data from, there is the problem...and I can't figure it out.
I am a newby with VBA so my knowledge is extremely limited. I have read about linking to a 'template' file with the connection strings, but not sure how to format the template file. Can someone show me an example? Also, how would I get it to loop thru each query stored in the database and then pull the appropriate connection string?
Examples
Here is an example of my connection string where 'AAL' is the investor code:
ODBC;DSN=SOTAMAS90;UID=tbard|AAL;PWD=password;Directory=\\mas-200\MAS90;Prefix=\\mas-200\MAS90\SY\, \\mas-200\MAS90\==\;ViewDLL=\\mas-200\MAS90\HOME;SERVER=NotTheServer
The query name for this would be MAS_AAL.
Another investor: SMP, the query name MAS_SMP. Etc, etc, etc...
Can someone be my light at the end of the tunnel and help me out so I don't have to manually run 300 queries. I'm dying over here!!
You can programmatically set the connection string.
There is a MAS 90 / MAS 200 ODBC driver called SOTAMAS90. On MAS installations in the last 5 years, there is both a 32 and a 64 bit driver.
In VBA, if I remember correctly, you would do something like this. (This assumes you already have fetched the Investor object you need, and it has properties called username and password):
Dim conn as new ADODB.Connection()
' Set properties of connection string manually
conn.ConnectionString = "DRIVER = SOTAMAS90; UID=" & myInvestor.username & "; PWD=" & myInvestor.password & "; Company=ABC"
conn.Open()
Another approach is to use a single ODBC connection within Access, to set up a linked ODBC table, using Access' Get External Data feature. Then you can treat it like any other Access table, and just query it directly. The problem with this approach is that Access will keep prompting you for credentials, both when you first open the table, and then if you are inactive for a while. I'm told you can save the UID and password in the SOTAMAS90 ODBC connection, but I've never done it.
Hope that helps.
Aaron

How to get user-Information from domino-server via vba

I writing a macro for ms word, that starts when the document is loaded and fills a few fields with user information (tel,email etc.). I want this information to come form our domino-servers, as they are our primary database.
I have tried using notes objects in vba to establish a session on the server, but that requires that user to keep their notes-client open(as far as I know), so thats not an option.
Currently I am trying to get the information via ldap request(the domino-server runs the ldap-service), however I cant find information on how the code and search string has to look like.
The last site I tried was this one (http://www.selfadsi.org/bind.htm), using the "Bind using special credentials" variant.
But I am getting a protocol error.(the string proably needs to be adjusted for connecting to domino, I tried "LDAP://[Server-FQN]/dc=DE" hoping it would show me all users registered as C=DE, but it did not work.)
I have also searched through IBMs Support Site and Knowledge-Center, but could not find the info I need.
If anyone could provide me an example on how to connect to the domino ldap and pull the information for a user, I would be very grateful.
There are two different sets of Notes objects available to you in VBA. There are OLE objects, which you access this way:
Set Session = CreateObject("Notes.NotesSession")
And there are COM objects, which you access this way:
Set Session = CreateObject("Lotus.NotesSession")
The key differences between them are that OLE objects require that the Notes client must be running and they also include the "front-end" classes like Notes.NotesUIWorkspace that can actually drive the Notes client, while the COM objects do not require that the Notes client is running (though either it, or the Domino server, must be installed) and it does not provide the front-end classes.
If you want to stick with the LDAP approach, the first thing you should probably do is download an LDAP client. I like the SoftTerra LDAP browser, but I've also heard that a lot of people like the Apache Directory Studio. Browsing the tree is really the best way to figure out what queries will get you the info you need.
s mentioned in the commment on Richards answer, I also tried finding the LDAP-String using a LDAP-Browser. Doing that and some testing with ADODB Objects I was able to come up with the following code:
Set objConnection = CreateObject("ADODB.Connection")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
Set objCommand = CreateObject("ADODB.Command")
Set objCommand.ActiveConnection = objConnection
objCommand.CommandText = "SELECT UID, mail FROM 'LDAP://[Server-FQN]:389 'WHERE ObjectClass='dominoPerson'"
Set objRecordSet = objCommand.Execute
While Not objRecordSet.EOF
varMail = objRecordSet.Fields("mail").Value
Debug.Print varMail(0)
objRecordSet.MoveNext
Wend
Which extracts the email-adress of all our users using anonymous access and prints the result into the debug window.
Now all I have to do is to adjust the WHERE-Statement to get the data I want per user. :-)

ODBC reading of BMC AR System / Remedy data to VS2010/VB .NET

Edit MY goal is this, I need to do read data from a Remedy Database using a VB .Net app. /Edit
I am trying to read data from the AR System ODBC driver in a VS 2010 VB windows form.
I have added a connection in the data connections via , a system dsn, connection string pulled from a working excel data pull, and built a connection string based via the wizard.
I can test connection, and it comes back 'test connection succeeded'.
When I click ok and the Data connection goes to my server explorer, it expands to tables, view, and procedures and viewing/refreshing those causes errors such as:
Column 'Table_Cat' does not belong to table Tables.
Error [im00][ar system odbc driver] not supported
I am aware there is the api out there, however this has a problem in that the api acts like a login session from the client, which limits you to one login session. This not feasible for the task at hand as the user needs to remain logged into remedy, and the app I'm writing will be read only for data.
The goal is a billboard app that will display certain tickets, kind of like a stock ticker.
There will be no editing of ticket data from remedy, I just need to read the tickets and provide tallies and alerts for our helpdesk.
It seemed so easy when I sat down, but now 4 hours later and a mind numbing amount of irrelevant google results, I'm almost wondering if I'm going to have to report back that it cannot be done with out the api and creating more remedy accounts. Not having to create additional remedy accounts was part of of the request put to me.
Tags: Visual Studio 2010 BMC AR System Remedy ODBC VB.NET
Update
So I have done the code by hand and now seem a few steps forward, but still blind.
Ok, so if i export my excel query it looks like this from the dqy file
export.dqy
DRIVER={AR System ODBC Driver};ARServer=xxxxxx;ARServerPort=xxxxx;UID=xxxx;PWD=xxxx;ARAuthentication=;SERVER=NotTheServer
SELECT "EN:HelpDesk"."Company Name", "EN:HelpDesk"."Call Status", "EN:HelpDesk"."Caller Region", "EN:HelpDesk"."Next Action", "EN:HelpDesk"."Detailed Description(FTS)", "EN:HelpDesk".Device, "EN:HelpDesk"."Submitted-by", "EN:HelpDesk".Impact, "EN:HelpDesk"."Arrival Time", "EN:HelpDesk"."Call Id", "EN:HelpDesk".Market FROM "EN:HelpDesk" "EN:HelpDesk" WHERE ("EN:HelpDesk"."Call Status"<>'Closed') AND ("EN:HelpDesk"."Submitted-by"<>'nis') AND ("EN:HelpDesk".Impact='High') AND ("EN:HelpDesk".Market='DCIN') AND ("EN:HelpDesk"."Caller Region"<>'UK')
First off, these quotes look wrong to me, but it seems to work because if I leave them, executing the command doesn't fail, however it doesn't return data to my data grid view in vb.
Second the EN:Helpdesk looks odd to me but again same results as the quotes.
I have tried changing the quotes to brackets [ ] but receive errors once I do.
Here is my code:
VB Code
Imports SystemM My goal
Imports System.Data
Imports System.Data.Odbc
Imports System.Data.SqlClient
Sub Main()
Dim sql As String
Dim connectionString As String = "DRIVER={AR System ODBC Driver};ARServer=xxx;ARServerPort=xxx;UID=xxx;PWD=xxx;ARAuthentication=;SERVER=NotTheServer"
sql = "SELECT ""EN:HelpDesk"".""Company Name"", ""EN:HelpDesk"".""Call Status"", ""EN:HelpDesk"".""Caller Region"", ""EN:HelpDesk"".""Next Action"", ""EN:HelpDesk"".""Detailed Description(FTS)"", ""EN:HelpDesk"".Device, ""EN:HelpDesk"".""Submitted-by"", ""EN:HelpDesk"".Impact, ""EN:HelpDesk"".""Arrival Time"", ""EN:HelpDesk"".""Call Id"", ""EN:HelpDesk"".Market FROM EN:HelpDesk WHERE (""EN:HelpDesk"".""Call Status""<>'Closed') AND (""EN:HelpDesk"".""Submitted-by""<>'nis') AND (""EN:HelpDesk"".Impact='High') AND (""EN:HelpDesk"".Market='DCIN') AND (""EN:HelpDesk"".""Caller Region""<>'UK')"
Dim bindingSource1 As New BindingSource()
Me.SQLDS_reportresults.DataSource = bindingSource1
Dim myAdapter = New OdbcDataAdapter(sql, connectionString)
Dim commandBuilder As New OdbcCommandBuilder(myAdapter)
Dim table As New DataTable()
table.Locale = System.Globalization.CultureInfo.InvariantCulture
myAdapter.Fill(table)
bindingSource1.DataSource = table
Me.SQLDS_reportresults.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCellsExceptHeader)
End Sub
Project is a windows forms with a button to activate main(), a textbox (textbox1) and a datagridview(SQLDS_reportresults).
As the code stands, this causes no errors, but my datagridview never populates. Since there are no errors, I'm inclined to think my connection is working , and that my command is being executed,making my problem lay in code, however given the funky use of quotes and en:helpdesk in the sql command, I'm also concerned that is malformed and causing the where portion to return no results.
Anyone have any suggestions / ideas?
I need a way to display these results in app, and right now I don't care how just as long as I can see some data at all.
I've been googling and looked at the vb examples in the api zip but that is not related to opening a odbc connection and I found that of little help in my research.
I almost feel like I'm missing something simple or obvious.
When i run odbcad32.exe my ar system odbc driver shows 7.00.01.02 which is what I assume is installed on everyones machines as I used the remedy install set provided to me by the IT/Software admins to build this dev box.

How do I connect to a Lotus Notes DB through VBA?

I'm trying to connect to a Lotus Notes database via VBA in Microsoft Access 2003. The code I have is as follows:
Set nSession = CreateObject("Notes.NotesSession")
Set nDatabase = nSession.GetDatabase("CN=MT_N01/O=Org Name", "LossPrevention\BrchPrVI.nsf", False)
I've tried variations for the server name, but nothing seems to work. In Lotus Notes it appears as "Server: MT_N01/Org Name". I've tried just "MT_N01" and "MT_N01/Org Name", but the NotesDatabase variable keeps ending up empty.
Any tips?
I might be wrong here, but I think you should call the Initialize() method of the session prior to using it.
Take a look at the samples here: http://www.ibm.com/developerworks/lotus/library/domino-msnet/index.html
I think that behaviour is normal; VBA knows nDatabase is a variant/object, but does not know anything about its contents. At least that is what I get when I try your code in Excel 2003.
Try to return something from the database object, for example nDatabase.ReplicaID should return the database identity string. If the databas is not properly loaded, you will get an error.
Many good links are posted in response to the ".NET and Lotus Notes Interop." question.
Unless you also need to us the NotesUIWorkspace class and its child classes to manipulate the Notes client user interface, you should be using the "Lotus.NotesSession" class instead of the "Notes.NotesSession" class. And as per the answer from #Sagultay, you should be calling nSession.Intialize().

Intermittent error when attempting to control another database

I have the following code:
Dim obj As New Access.Application
obj.OpenCurrentDatabase (CurrentProject.Path & "\Working.mdb")
obj.Run "Routine"
obj.CloseCurrentDatabase
Set obj = Nothing
The problem I'm experimenting is a pop-up that tells me Access can't set the focus on the other database. As you can see from the code, I want to run a Subroutine in another mdb. Any other way to achieve this will be appreciated.
I'm working with MS Access 2003.
This is an intermittent error. As this is production code that will be run only once a month, it's extremely difficult to reproduce, and I can't give you the exact text and number at this time. It is the second month this happened.
I suspect this may occur when someone is working with this or the other database.
The dataflow is to update all 'projects' once a month in one database and then make this information available in the other database.
Maybe, it's because of the first line in the 'Routines' code:
If vbNo = MsgBox("Do you want to update?", vbYesNo, "Update") Then
Exit Function
End If
I'll make another subroutine without the MsgBox.
I've been able to reproduce this behaviour. It happens when the focus has to shift to the called database, but the user sets the focus ([ALT]+[TAB]) on the first database. The 'solution' was to educate the user.
This is an intermittent error. As this is production code that will be run only once a month, it's extremely difficult to reproduce, and I can't give you the exact text and number at this time. It is the second month this happened.
I suspect this may occur when someone is working with this or the other database.
The dataflow is to update all 'projects' once a month in one database and then make this information available in the other database.
Maybe, it's because of the first line in the 'Routines' code:
If vbNo = MsgBox("Do you want to update?", vbYesNo, "Update") Then
Exit Function
End If
I'll make another subroutine without the MsgBox.
I've tried this in our development database and it works. This doesn't mean anything as the other code also workes fine in development.
I guess this error message is linked to the state of one of your databases. You are using here Jet connections and Access objects, and you might not be able, for multiple reasons (multi-user environment, unability to delete LDB Lock file, etc), to properly close your active database and open another one. So, according to me, the solution is to forget the Jet engine and to use another connexion to update the data in the "other" database.
When you say "The dataflow is to update all 'projects' once a month in one database and then make this information available in the other database", I assume that the role of your "Routine" is to update some data, either via SQL instructions or equivalent recordset updates.
Why don't you try to make the corresponding updates by opening a connexion to your other database and (1) send the corresponding SQL instructions or (2) opening recordset and making requested updates?
One idea would be for example:
Dim cn as ADODB.connexion,
qr as string,
rs as ADODB.recordset
'qr can be "Update Table_Blablabla Set ... Where ...
'rs can be "SELECT * From Table_Blablabla INNER JOIN Table_Blobloblo
set cn = New ADODB.connexion
cn.open
You can here send any SQL instruction (with command object and execute method)
or open and update any recordset linked to your other database, then
cn.close
This can also be done via an ODBC connexion (and DAO.recordsets), so you can choose your favorite objects.
If you would like another means of running the function, try the following:
Dim obj As New Access.Application
obj.OpenCurrentDatabase (CurrentProject.Path & "\Working.mdb")
obj.DoCmd.RunMacro "MyMacro"
obj.CloseCurrentDatabase
Set obj = Nothing
Where 'MyMacro' has an action of 'RunCode' with the Function name you would prefer to execute in Working.mdb
I've been able to reproduce the error in 'development'.
"This action cannot be completed because the other application is busy. Choose 'Switch To' to activate ...."
I really can't see the rest of the message, as it is blinking very fast. I guess this error is due to 'switching' between the two databases. I hope that, by educating the user, this will stop.
Philippe, your answer is, of course, correct. I'd have chosen that path if I hadn't developed the 'routine' beforehand.
"I've been able to reproduce this behaviour. It happens when the focus has to shift to the called database, but the user sets the focus ([ALT]+[TAB]) on the first database. The 'solution' was to educate the user." As it is impossible to prevent the user to switch application in Windows, I'd like to close the subject.