"Cannot open SQL server" error -- but using Access? - ms-access

I wanted to open the CR, while clicking a button on the form in VB 6.0. This is the code i've used:
CrystalReport1.ReportFileName = "D:\VISUAL BASIC\monrep.rpt"
CrystalReport1.RetrieveDataFiles
CrystalReport1.Action = 1
But when I try to execute i ran into "Cannot open SQL server" error. But I've used Access as the database file. I wanted only to open the CR Showing the contents of a particular table. I'm using CR 8.5. Can anyone help me regarding this?

This may Help you
Public Sub OpenReport(ReportPath As String, DataPath As String)
' 1) add a reference to the Crystal Reports 8.5 ActiveX Designer Run Time Library
' 2) place a CrystalActiveXReportViewer control named crView to your form
Dim oCRapp As CRAXDRT.Application
Dim oReport As CRAXDRT.Report
Set oCRapp = New CRAXDRT.Application
Set oReport = oCRapp.OpenReport(ReportPath, crOpenReportByTempCopy)
SetReportDatabase oReport, DataPath
crView.ReportSource = oReport
crView.ViewReport
End Sub
Public Sub SetReportDatabase(CrystalRpt As CRAXDRT.Report, DataPath As String)
Dim oTab As CRAXDRT.DatabaseTable
On Error GoTo errhndl
For Each oTab In CrystalRpt.Database.Tables
' check connection type
If LCase$(oTab.DllName) = "crdb_odbc.dll" Then
With oTab.ConnectionProperties
.DeleteAll
.Add "Connection String", "Driver={Microsoft Access Driver (*.mdb, *.accdb)};Dbq=" & DataPath & ";Uid=Admin;Pwd=MyPassword"
End With
End If
Next oTab
' subreports
Dim rptObj As Object, rptObjs As CRAXDRT.ReportObjects, rptSecs As CRAXDRT.Sections, rptSec As CRAXDRT.Section
Dim subRptObj As CRAXDRT.SubreportObject, oSubTab As CRAXDRT.DatabaseTable
Dim subRpt As CRAXDRT.Report
Set rptSecs = CrystalRpt.Sections
For Each rptSec In rptSecs
Set rptObjs = rptSec.ReportObjects
For Each rptObj In rptObjs
If rptObj.Kind = crSubreportObject Then
Set subRptObj = rptObj
Set subRpt = subRptObj.OpenSubreport
For Each oSubTab In subRpt.Database.Tables
If oSubTab.DllName = "crdb_odbc.dll" Then
With oSubTab.ConnectionProperties
.DeleteAll
.Add "Connection String", "Driver={Microsoft Access Driver (*.mdb, *.accdb)};Dbq=" & DataPath & ";Uid=Admin;Pwd=MyPassword"
End With
End If
Next oSubTab
End If
Next rptObj
Next rptSec
Exit Sub
errhndl:
Err.Raise Err.Number, "SetReportDatabase", Err.Description
End Sub

Related

MS Access VBA File Dialog Crashing

From MS Access I am generating several MS Access Workbooks. Via the following code I am getting the desired save location for all of the workbooks. The following code was working without issues a few days ago. Now it abruptly fails with no error number. MS Access crashes and I get a prompt to restart MS Access and a backup file is automatically created of the MS Access project I am working on.
Strangely the code works fine if I step through it with the debugger. It simply is not working at full speed.
UPDATE 1:
If I do the falling the save_location call works.
Private Sub make_report()
' TODO#: Change to late binding when working
Dim strSaveLocation as string
Dim xl as Excel.Application
dim wb as Excel.Workbook
strSaveLocation = save_location("G:\Group2\Dev\z_report")
Set xl=New Excel.Application
' do workbook stuff
With xl
strSaveLocation = strSaveLocation & "\report_name.xlsx"
wb.SaveAs strSavelLocation, xlOpenXMLWorkbook
End With ' xl
Set xl=nothing
End Sub
If I call the save_location function like this it abruptly crashes MS Access. It doesn't throw an error or anything. It just crashes.
Private Sub make_report()
' TODO#: Change to late binding when working
Dim strSaveLocation as string
Dim xl as Excel.Application
dim wb as Excel.Workbook
Set xl=New Excel.Application
' do workbook stuff
With xl
' the call to save_location is inside of the xl procedure
strSaveLocation = save_location("G:\Group2\Dev\z_report")
strSaveLocation = strSaveLocation & "\report_name.xlsx"
wb.SaveAs strSavelLocation, xlOpenXMLWorkbook
End With ' xl
Set xl=nothing
End Sub
By moving the save_location call inside the Excel.Application work string it fails. I don't understand why.
Private Function save_location(Optional ByVal initialDir As String) As String
On Error GoTo err_trap
Dim fDialog As Object
Dim blMatchIniDir As Boolean
Set fDialog = Application.FileDialog(4) ' msoFileDialogFolderPicker
With fDialog
.Title = "Select Save Location"
If NOT (initialDir=vbnullstring) then
.InitialFileName = initialDir
End If
If .Show = -1 Then
' item selected
save_location = .SelectedItems(1)
End If
End With
Set fDialog = Nothing
exit_function:
Exit Function
err_trap:
Select Case Err.Number
Case Else
Debug.Print Err.Number, Err.Description
Stop
Resume
End Select
End Function
Actions tried:
Decompile project and recompile
Create new MS Access project and import all objects
Compact and repair
Reset all reference
Notes:
I am using the client's system and
I don't know of any system updates
Client's system is a virtual desktop via VMWare
Office 2013
Windows 7 Pro
while i am not sure if this is the specific problem - but if it is the case, it messes with anything VBA. Check the folder names and file names for any apostrophes. While windows allows this, an apostrophe will be seen in VBA as a comment, and will crash it. Have the client walk you through the exact file that he selects to confirm there is no apostrophe character in the filename or folder name.

VBA The object you entered is not a valid recordset property

Ok so what I am trying to do is assign a ADODB.Recordset to a ListBox in VBA. I am getting the Error: "The object you entered is not a valid recordset property".. What am I doing wrong here?
Note: adoConn is valid and set somewhere else in the code.
Private Sub Form_Load()
' Error Management
On Error GoTo ErrHandler:
Dim adoRS As New ADODB.Recordset
Dim sqlStmt As String
' Create the SQL statement
sqlStmnt = "SELECT GroupName FROM tblGroups"
' Execute the statement
adoRS.Open sqlStmnt, adoConn
' Add items to the lstGroups
If (adoRS.RecordCount <> 0) Then
Set lstGroups.Recordset = adoRS
End If
' Clean up
adoRS.Close
Set adoRS = Nothing
Exit Sub
ErrHandler:
' Clean up
If (adoRS.State = adStateOpen) Then
adoRS.Close
End If
Set adoRS = Nothing
If Err <> 0 Then
MsgBox Err.Source & "-->" & Err.Description, , "Error"
End If
End Sub
This is how ADO is opened
Public Sub openConnection()
' The path to the database
Dim strDBPath As String
strDBPath = "C:\Users\Vincent\****\****\"
' The database name to connect to
Dim strDBName As String
strDBName = "Permissions_be.accdb"
' Full path to the database
Dim strDBFull As String
strDB = strDBPath & "\" & strDBName
' Instantiate an ADO object
Set adoConn = New ADODB.Connection
' Connect to database
With adoConn
.Provider = "Microsoft.ACE.OLEDB.12.0"
.Mode = adModeShareDenyNone
.Open (strDBPath & strDBName)
End With
End Sub
Update
So if anyone comes across this problem on Access 2010/13.
- Set the list box to a values list.
- Then on the VBA side loop through the recordset
' Add items to the lstGroups
If (adoRS.RecordCount <> 0) Then
Do While Not adoRS.EOF
' This is how to add two columns to one listbox if you need only
' one then put only the (adoRS.Fields(0))
lstGroups.AddItem (adoRS.Fields(0) & ";" & adoRS.Fields(1))
adoRS.MoveNext
Loop
lstGroups.Requery
End If
The problem is this line
Set lstGroups.Recordset = adoRS
If you look at the documentation you will notice that the is not a "Recordset" property in the list.
There is a property of the ListBox called List and it accepts a variant array. You can get the values from the record set and put them into an array and then onto the List.
Something like
' Add items to the lstGroups
If (adoRS.RecordCount <> 0) Then
lstGroups.List= adoRS.GetRows
End If
I did not test any of this but it might get you in the right track.
Also if you do not get it to work with the list this link has a very good example on how to add them one by one
enter link description here
how do you set you adoConn ? should be something like below :-
Dim cnn As ADODB.Connection
Set adoConn= New ADODB.Connection
With adoConn
.Provider = "Microsoft.Access.OLEDB.10.0"
.Properties("Data Provider").Value = "SQLOLEDB"
.Properties("Data Source").Value = "10.******"
.Properties("User ID").Value = "*****readonly"
.Properties("Password").Value = "*****readonly"
.Open
End With

What are the Access startup properties that can be changed using VBA

I have an app that uses the following procedure to change some of the Current DB properties.
Public Sub SetStartupOptions(propname As String, propdb As Variant, prop As Variant)
On Error GoTo Err_SetStartupOptions
'Set passed startup property.
'some of the startup properties you can use...
' "StartupShowDBWindow", DB_BOOLEAN, False
' "StartupShowStatusBar", DB_BOOLEAN, False
' "AllowBuiltinToolbars", DB_BOOLEAN, False
' "AllowFullMenus", DB_BOOLEAN, False
' "AllowBreakIntoCode", DB_BOOLEAN, False
' "AllowSpecialKeys", DB_BOOLEAN, False
' "AllowBypassKey", DB_BOOLEAN, False
Dim dbs As Object
Dim prp As Object
Set dbs = CurrentDb
If propname = "DBOpen" Then
dbs.Properties("AllowBreakIntoCode") = prop
dbs.Properties("AllowSpecialKeys") = prop
dbs.Properties("AllowBypassKey") = prop
dbs.Properties("AllowFullMenus") = prop
dbs.Properties("StartUpShowDBWindow") = prop
Else
dbs.Properties(propname) = prop
End If
Set dbs = Nothing
Set prp = Nothing
Exit_SetStartupOptions:
Exit Sub
Err_SetStartupOptions:
Select Case Err.Number
Case 3270
Set prp = dbs.CreateProperty(propname, propdb, prop)
Resume Next
Case Else
Dim ErrAns As Integer, ErrMsg As String
If ErrChoice = vbYesNoCancel Then
ErrMsg = Err.Description & ": " & Str(Err.Number) & vbNewLine & "Press 'Yes' to resume next;" & vbCrLf & _
"'No' to Exit Procedure." & vbCrLf & "or 'Cancel' to break into code"
Else
ErrMsg = Err.Description & ": " & Str(Err.Number) & vbNewLine & "Press 'Yes' to resume next;" & vbCrLf & _
"'No' to Exit Procedure."
End If
ErrAns = MsgBox(ErrMsg, _
vbCritical + vbQuestion + ErrChoice, "SetStartupOptions")
If ErrAns = vbYes Then
Resume Next
ElseIf ErrAns = vbCancel Then
On Error GoTo 0
Resume
Else
Resume Exit_SetStartupOptions
End If
End Select
End Sub
procedure can be used to add and set values for DB.properties, These are the properties that are set in the Access options screen. I have a limited list of property names but, does anyone know where I can find the full list of properties that are recognized? ( i.e. the startup form name, start up ribbon name,... )
You can list all of the properties for the database that exist at the time you run the code using a very simple procedure as seen here.
Public Sub ListDBProps()
Dim db As Database
Dim prp As Property
Set db = CurrentDb
For Each prp In db.Properties
Debug.Print prp.Name
Next prp
End Sub
There are a couple of gotcha's in this. Notice I said "that exist at the time you run the code". That is, Access creates properties for the database (and presumably other objects as well) on an "as needed" basis. For instance, when you compile the database into, what used to be called an MDE, now an ACCDE, Access will add a new property of Type "Text" [10] named "MDE" with a value of "T". There are a couple of properties in the list you provided that fall into this category as well, such as "AllowBypassKey" and "AllowBreakIntoCode".
Here is the list that I got when I ran this code on a simple database I opened up:
Name
Connect
Transactions
Updatable
CollatingOrder
QueryTimeout
Version
RecordsAffected
ReplicaID
DesignMasterID
Connection
ANSI Query Mode
Themed Form Controls
AccessVersion
NavPane Category
UseMDIMode
ShowDocumentTabs
Build
CheckTruncatedNumFields
ProjVer
StartUpShowDBWindow
StartUpShowStatusBar
AllowShortcutMenus
AllowFullMenus
AllowBuiltInToolbars
AllowToolbarChanges
AllowSpecialKeys
UseAppIconForFrmRpt
AllowDatasheetSchema
Show Values Limit
Show Values in Indexed
Show Values in Non-Indexed
Show Values in Remote
Auto Compact
DesignWithData
Picture Property Storage Format
NavPane Closed
NavPane Width
NavPane View By
NavPane Sort By
Track Name AutoCorrect Info
Perform Name AutoCorrect
HasOfflineLists
You can add the Type property to your output easily enough. It is an integer value corresponding to the DataTypeEnum enumeration. The Value property of the Property can be a little more tricky. Usually it's a value that can be easily converted to a string value but there are a couple that cause a runtime error when you try to print them out or store them in a String variable. A little error handling in a small function can handle that with no trouble.
My example was run on an ACCDB in Microsoft Access 2007.
Enjoy . . . Doug

How do I utilize Access 2007 Linked Table Manager in C#

Scenario: I have a Front End and a Back End Access 2007 Database that are currently linked to each other through the Linked Table Manager Database Tool. The Back End DB is going to be moved to a location on a server. The server name will be different for each facility and there are about 40 or so now which will increase throughout the year.
What I need to try to accomplish is changing the linked tables programatically. I will need to build the linked string to something like:
\\something\facilitynum(gathered from Environment variable)\c$\somefolder\.
I have found that the column Database in MSysObjects contains the link string that would need to be changed. The question becomes, how do get permissions to change a System table or use some .dll that will allow me to change the link to the newly built string?
Everything that I have found so far always leads back to manually changing the link within the Access Database.
You can programmatically change the link from within Access (using VBA) like so (this uses a dsn file to contain the actual server information)
Private Sub UpdateDSN()
On Error GoTo ErrorHandler
Dim dbPath As String
Dim connStr As String
Dim Tdf As TableDef
dbPath = Application.CodeDb.Name
dbPath = Left(dbPath, InStr(dbPath, Dir(dbPath)) - 1)
For Each Tdf In CurrentDb.TableDefs
connStr = Tdf.Connect
If InStr(1, UCase(connStr), "ODBC") Then
connStr = "odbc; FILEDSN=" & dbPath & "db.dsn;"
Tdf.Connect = connStr
Tdf.RefreshLink
End If
Next
Dim fName As String
Dim fNumber As Integer
Dim InputStr As String
fNumber = FreeFile()
fName = dbPath & "db.dsn"
Dim serverName As String
Open fName For Input As fNumber
Do While Not EOF(fNumber)
Line Input #fNumber, InputStr
If InStr(1, UCase(InputStr), "SERVER=") > 0 Then
serverName = Right(InputStr, Len(InputStr) - _
(InStr(1, InputStr, "SERVER=") + 6))
End If
Loop
ErrorHandler:
On Error GoTo 0
DoCmd.OpenForm "Main"
cap = Forms!main.Caption
If InStr(1, cap, "(") > 1 Then
cap = Left(cap, InStr(1, cap, "("))
End If
Forms!main.Caption = "db" & " (" & serverName & ")"
End Sub

Mail merge started by VBA in Access let Word open Database again

I'm working on a Access database which generates some mails with mail merge called from VBA code in the Access database. The problem is that if I open a new Word document and start the mail merge (VBA), Word opens the same Access database (which is already open) to get the data. Is there any way to prevent this? So that the already opened instance of the database is used?
After some testing I get a strange behavior: If I open the Access database holding the SHIFT-Key the mail merge does not open an other Access instance of the same database. If I open the Access database without holding the key, I get the described behavior.
My mail merge VBA code:
On Error GoTo ErrorHandler
Dim word As word.Application
Dim Form As word.Document
Set word = CreateObject("Word.Application")
Set Form = word.Documents.Open("tpl.doc")
With word
word.Visible = True
With .ActiveDocument.MailMerge
.MainDocumentType = wdMailingLabels
.OpenDataSource Name:= CurrentProject.FullName, ConfirmConversions:=False, _
ReadOnly:=False, LinkToSource:=False, AddToRecentFiles:=False, _
PasswordDocument:="", PasswordTemplate:="", WritePasswordDocument:="", _
WritePasswordTemplate:="", Revert:=False, Format:=wdOpenFormatAuto, _
SQLStatement:="[MY QUERY]", _
SQLStatement1:="", _
SubType:=wdMergeSubTypeWord2000, OpenExclusive:=False
.Destination = wdSendToNewDocument
.Execute
.MainDocumentType = wdNotAMergeDocument
End With
End With
Form.Close False
Set Form = Nothing
Set word = Nothing
Exit_Error:
Exit Sub
ErrorHandler:
word.Quit (False)
Set word = Nothing
' ...
End Sub
The whole thing is done with Access / Word 2003.
Update #1
It would also help if someone could tell me what the exact difference is between opening Access with or without the SHIFT-Key. And if it is possible to write some VBA code to enable the "features" so if the database is opened without the SHIFT-Key, it at least "simulates" it.
Cheers,
Gregor
When I do mailmerges, I usually export a .txt file from Access and then set the mail merge datasource to that. That way Access is only involved in exporting the query and then telling the Word document to do the work via automation, roughly as follows:
Public Function MailMergeLetters()
Dim pathMergeTemplate As String
Dim sql As String
Dim sqlWhere As String
Dim sqlOrderBy As String
'Get the word template from the Letters folder
pathMergeTemplate = "C:\MyApp\Resources\Letters\"
'This is a sort of "base" query that holds all the mailmerge fields
'Ie, it defines what fields will be merged.
sql = "SELECT * FROM MailMergeExportQry"
With Forms("MyContactsForm")
' Filter and order the records you want
'Very much to do for you
sqlWhere = GetWhereClause()
sqlOrderBy = GetOrderByClause()
End With
' Build the sql string you will use with this mail merge
sql = sql & sqlWhere & sqlOrderBy & ";"
'Create a temporary QueryDef to hold the query
Dim qd As DAO.QueryDef
Set qd = New DAO.QueryDef
qd.sql = sql
qd.Name = "mmexport"
CurrentDb.QueryDefs.Append qd
' Export the data using TransferText
DoCmd.TransferText _
acExportDelim, , _
"mmexport", _
pathMergeTemplate & "qryMailMerge.txt", _
True
' Clear up
CurrentDb.QueryDefs.Delete "mmexport"
qd.Close
Set qd = Nothing
'------------------------------------------------------------------------------
'End Code Block:
'------------------------------------------------------------------------------
'------------------------------------------------------------------------------
'Start Code Block:
'OK. Access has built the .txt file.
'Now the Mail merge doc gets opened...
'------------------------------------------------------------------------------
Dim appWord As Object
Dim docWord As Object
Set appWord = CreateObject("Word.Application")
appWord.Application.Visible = True
' Open the template in the Resources\Letters folder:
Set docWord = appWord.Documents.Add(Template:=pathMergeTemplate & "MergeLetters.dot")
'Now I can mail merge without involving currentproject of my Access app
docWord.MailMerge.OpenDataSource Name:=pathMergeTemplate & "qryMailMerge.txt", LinkToSource:=False
Set docWord = Nothing
Set appWord = Nothing
'------------------------------------------------------------------------------
'End Code Block:
'------------------------------------------------------------------------------
Finally:
Exit Function
Hell:
MsgBox Err.Description & " " & Err.Number, vbExclamation, APPHELP
On Error Resume Next
CurrentDb.QueryDefs.Delete "mmexport"
qd.Close
Set qd = Nothing
Set docWord = Nothing
Set appWord = Nothing
Resume Finally
End Function
To use this, you need to set up your Resources\Letters subfolder and put your mailmerge template word file in there. You also need your "base" query with the field definitions in your Access App (in the example, it is called MailMergeExportQry. But you can call it anything.
You also need to figure out what filtering and sorting you will do. In the example, this is represented by
sqlWhere = GetWhereClause()
sqlOrderBy = GetOrderByClause
Once you have got your head round those things, this is highly reusable.