How to get a list of installed OLE DB providers? - excel

Microsoft Excel allows import of data from "Other Sources". One of the options is to use an OLE DB provider.
How to get a list of available OLE DB providers?

If you have powershell available, just paste this into a powershell command prompt:
foreach ($provider in [System.Data.OleDb.OleDbEnumerator]::GetRootEnumerator())
{
$v = New-Object PSObject
for ($i = 0; $i -lt $provider.FieldCount; $i++)
{
Add-Member -in $v NoteProperty $provider.GetName($i) $provider.GetValue($i)
}
$v
}
Credits and more advanced usage:
http://dbadailystuff.com/list-all-ole-db-providers-in-powershell

I am answering my own question because this was harder to find that I expected. Google-fu could only answer part of my question; I needed to synthesize information from various blog entries and official documentation.
Below is VBScript you can copy/paste into a text file and run on Windows. You do not need local admin rights to run this version.
Depending on the size of your registry and speed on your CPU, it may take up to one minute to run. The result is a message box with text that can be copied to the clipboard with Ctrl+C.
Primary reference: https://sysmod.wordpress.com/2014/07/11/vbscript-to-list-installed-oledb-providers/
'List of installed OLEDB providers on local computer
Option Explicit
Const HKEY_CLASSES_ROOT = &H80000000
Const HKEY_CURRENT_USER = &H80000001
Const HKEY_LOCAL_MACHINE = &H80000002
Const HKEY_USERS = &H80000003
Const HKEY_CURRENT_CONFIG = &H80000005
Dim OutText, strComputer, objRegistry
Dim num
Dim ProgIdDict
strComputer = "."
Set objRegistry = GetObject("winmgmts:\\" & strComputer & "\root\default:StdRegProv")
OutText = "Note: Strike Ctrl+C to copy full text to clipboard"
Num = 1
Set ProgIdDict = CreateObject("Scripting.Dictionary")
' I discovered these registrations can appear in three different places.
' Use ProgIdDict to prevent dupes in the output
Append objRegistry, HKEY_CLASSES_ROOT, "HKEY_CLASSES_ROOT", "CLSID", ProgIdDict, Num, OutText
Append objRegistry, HKEY_LOCAL_MACHINE, "HKEY_LOCAL_MACHINE", "SOFTWARE\Classes\CLSID", ProgIdDict, Num, OutText
Append objRegistry, HKEY_LOCAL_MACHINE, "HKEY_LOCAL_MACHINE", "SOFTWARE\Classes\Wow6432Node\CLSID", ProgIdDict, Num, OutText
Sub Append(ByVal objRegistry, ByVal HKEYConstant, ByVal HKEYConstantStr, ByVal KeyPrefixStr, ByVal ProgIdDict, ByRef Num, ByRef OutText)
Dim Key, arrKeys
Dim strKeyPath, strValue, uValue
objRegistry.enumKey HKEYConstant, KeyPrefixStr, arrKeys
for each key in arrKeys
strKeyPath = KeyPrefixStr & "\" & key
' if key exists...
' I noticed something weird where non-MSOLAP entries use the first style,
' and MSOLAP entries use the second style.
If 0 = objRegistry.GetDWordValue(HKEYConstant, strKeyPath, "OLEDB_SERVICES", uValue) _
Or 0 = objRegistry.GetDWordValue(HKEYConstant, strKeyPath & "\OLEDB_SERVICES", "", uValue) _
Then
objRegistry.GetStringValue HKEYConstant,strKeyPath & "\ProgID","",strValue
If Not ProgIdDict.Exists(strValue) _
Then
ProgIdDict.Add strValue, strValue
OutText=OutText & vbcrlf & vbcrlf
'get the (Default) value which is the name of the provider
objRegistry.GetStringValue HKEYConstant,strKeyPath,"",strValue
OutText=OutText & num & ") " & strValue & vbcrlf & "Key: \\" & HKEYConstantStr & "\" & KeyPrefixStr & "\" & key
' and the expanded description
objRegistry.GetStringValue HKEYConstant,strKeyPath & "\OLE DB Provider","",strValue
OutText=OutText & vbcrlf & "OLE DB Provider: " & strValue
objRegistry.GetStringValue HKEYConstant,strKeyPath & "\ProgID","",strValue
OutText=OutText & vbcrlf & "ProgID: " & strValue
objRegistry.GetStringValue HKEYConstant,strKeyPath & "\VersionIndependentProgID","",strValue
OutText=OutText & vbcrlf & "VersionIndependentProgID: " & strValue
num = 1 + num
End If
end if
next
End Sub
Wscript.Echo OutText

Another solution using PowerShell, this time leveraging .NET code (credit to jrich523.wordpress.com).
Plug this into a PowerShell console:
(New-Object system.data.oledb.oledbenumerator).GetElements()
Produces output like this:
SOURCES_NAME : SQLOLEDB Enumerator
SOURCES_PARSENAME : {DFA22B8E-E68D-11d0-97E4-00C04FC2AD98}
SOURCES_DESCRIPTION : Microsoft OLE DB Enumerator for SQL Server
SOURCES_TYPE : 2
SOURCES_ISPARENT : False
SOURCES_CLSID : {DFA22B8E-E68D-11d0-97E4-00C04FC2AD98}

In Windows Explorer:
Create a text file anywhere. e.g. temp.txt.
Change the extension to "udl". E.g. temp.udl.
Double click temp.udl.
Go to the [Provider] Tab. Observe the list of "OLE

OLEDB provides a class that will enumerate all OLE DB providers for you.
Microsoft OLE DB Root Enumeratorđź•—
ProgID: "MSDAENUM"
clsid: {c8b522d0-5cf3-11ce-ade5-00aa0044773d}
CLSID_OLEDB_ENUMERATOR (from msdaguid.h in the sdk)
The steps
Create the enumerator
ISourcesRowset enum = (ISourcesRowset)CreateComObject(CLSID_OLEDB_ENUMERATOR);
Get the results as an OLEDB IRowset:
IRowset rowset = enum.GetSourcesRowset(null, IRowset, 0, null);
The IRowset interface, like the rest of OLEDB is...merciless. It's a nightmare of API, dreamed up in a time when Java was all the rage. Fortunately Microsoft created a friendly wrapper around OLEDB: called ActiveX Data Object (ADO). It even provides a handy function to wrap an OLEDB IRowset into an ADO Recordset (adapter pattern):
Recordset rs = (Recordset)CreateComObject(CLASS_Recordset);
(rs as ADORecordsetConstruction).Rowset = rowset;
Now you can iterate the results:
SOURCES_NAME SOURCES_PARSENAME SOURCES_DESCRIPTION SOURCES_TYPE SOURCES_ISPARENT SOURCES_CLSID
-------------------------- -------------------------------------- ---------------------------------------------------- ------------ ---------------- --------------------------------------
SQLOLEDB {0C7FF16C-38E3-11d0-97AB-00C04FC2AD98} Microsoft OLE DB Provider for SQL Server 1 False {0C7FF16C-38E3-11d0-97AB-00C04FC2AD98}
MSOLAP {10154F28-4979-4166-B114-3E7A7926C747} Microsoft OLE DB Provider for Analysis Services 10.0 1 False {10154F28-4979-4166-B114-3E7A7926C747}
MSOLAP {10154F28-4979-4166-B114-3E7A7926C747} Microsoft OLE DB Provider for Analysis Services 10.0 3 False {10154F28-4979-4166-B114-3E7A7926C747}
MSDataShape {3449A1C8-C56C-11D0-AD72-00C04FC29863} MSDataShape 1 False {3449A1C8-C56C-11D0-AD72-00C04FC29863}
SQLNCLI11 {397C2819-8272-4532-AD3A-FB5E43BEAA39} SQL Server Native Client 11.0 1 False {397C2819-8272-4532-AD3A-FB5E43BEAA39}
ADsDSOObject {549365d0-ec26-11cf-8310-00aa00b505db} OLE DB Provider for Microsoft Directory Services 1 False {549365d0-ec26-11cf-8310-00aa00b505db}
MSOLEDBSQL {5A23DE84-1D7B-4A16-8DED-B29C09CB648D} Microsoft OLE DB Driver for SQL Server 1 False {5A23DE84-1D7B-4A16-8DED-B29C09CB648D}
MSOLEDBSQL Enumerator {720818D5-1465-4812-839F-9F15C38A52CB} Microsoft OLE DB Driver for SQL Server Enumerator 2 False {720818D5-1465-4812-839F-9F15C38A52CB}
SQLNCLI11 Enumerator {8F612DD2-7E28-424f-A2FD-C2EECC314AA2} SQL Server Native Client 11.0 Enumerator 2 False {8F612DD2-7E28-424f-A2FD-C2EECC314AA2}
Windows Search Data Source {9E175B8B-F52A-11D8-B9A5-505054503030} Microsoft OLE DB Provider for Search 1 False {9E175B8B-F52A-11D8-B9A5-505054503030}
MSDASQL {c8b522cb-5cf3-11ce-ade5-00aa0044773d} Microsoft OLE DB Provider for ODBC Drivers 1 False {c8b522cb-5cf3-11ce-ade5-00aa0044773d}
MSDASQL Enumerator {c8b522cd-5cf3-11ce-ade5-00aa0044773d} Microsoft OLE DB Enumerator for ODBC Drivers 2 False {c8b522cd-5cf3-11ce-ade5-00aa0044773d}
MSOLAP {DBC724B0-DD86-4772-BB5A-FCC6CAB2FC1A} Microsoft OLE DB Provider for Analysis Services 14.0 1 False {DBC724B0-DD86-4772-BB5A-FCC6CAB2FC1A}
MSOLAP {DBC724B0-DD86-4772-BB5A-FCC6CAB2FC1A} Microsoft OLE DB Provider for Analysis Services 14.0 3 False {DBC724B0-DD86-4772-BB5A-FCC6CAB2FC1A}
Microsoft.Jet.OLEDB.4.0 {dee35070-506b-11cf-b1aa-00aa00b8de95} Microsoft Jet 4.0 OLE DB Provider 1 False {dee35070-506b-11cf-b1aa-00aa00b8de95}
SQLOLEDB Enumerator {DFA22B8E-E68D-11d0-97E4-00C04FC2AD98} Microsoft OLE DB Enumerator for SQL Server 2 False {DFA22B8E-E68D-11d0-97E4-00C04FC2AD98}
MSDAOSP {dfc8bdc0-e378-11d0-9b30-0080c7e9fe95} Microsoft OLE DB Simple Provider 1 False {dfc8bdc0-e378-11d0-9b30-0080c7e9fe95}
MSDAORA {e8cc4cbe-fdff-11d0-b865-00a0c9081c1d} Microsoft OLE DB Provider for Oracle 1 False {e8cc4cbe-fdff-11d0-b865-00a0c9081c1d}
Microsoft documents the columns in ISourcesRowset::GetSourcesRowset archive
SOURCES_NAME (0): The invariant name of the data store or enumerator.
SOURCES_PARSENAME (1): String to pass to IParseDisplayName to obtain a moniker for the data source object or enumerator.
SOURCES_DESCRIPTION (2): Description of the OLE DB data source object or enumerator.
SOURCES_TYPE (3): Specifies whether the row describes a data source object or an enumerator:
DBSOURCETYPE_DATASOURCE_TDP (1): Indicating a tabular data provider
DBSOURCETYPE_ENUMERATOR (2): Indicating an enumerator
DBSOURCETYPE_DATASOURCE_MDP (3): Indicating a multidimensional (OLAP) provider
DBSOURCETYPE_BINDER (4): Indicating a provider binder that supports direct URL binder
If a single piece of code is capable of being used both as a data source object and as an enumerator, it is listed in the rowset twice, once in each role.
SOURCES_ISPARENT (4): If the row describes an enumerator, SOURCES_ISPARENT is VARIANT_TRUE if the enumerator is the parent enumerator; that is, the enumerator whose enumeration contains the enumerator on which ISourcesRowset::GetSourcesRowset was just called. This allows the consumer to go backward through the enumeration. Whether an enumerator is able to enumerate its parent is provider-specific. Otherwise, SOURCES_ISPARENT is VARIANT_FALSE.
If the row describes a data source object, SOURCES_ISPARENT is ignored by the consumer.

I had an issue where Steinar Herland's powershell script wasn't finding my oledb provider. I wrote a little C# program that did though.
using System.Data.OleDb;
var oleEnum = new OleDbEnumerator();
var elems = oleEnum.GetElements();
if (elems != null && elems.Rows != null)
foreach (System.Data.DataRow row in elems.Rows)
if (!row.IsNull("SOURCES_NAME") && row["SOURCES_NAME"] is string)
Console.WriteLine(row["SOURCES_NAME"]);

If you have MS Excel installed, why go thru all the hassle of all these scripts/powershell? You can use Excel Import Data from Other Source and it will display all installed OLEDB Data Sources.

I edited the code by #Steinar Herland
If you want only to display the ACCESS OLEDB Providers, just paste this into a powershell command prompt:
foreach ($provider in [System.Data.OleDb.OleDbEnumerator]::GetRootEnumerator())
{
if ($provider.GetValue(0) -like "Microsoft.ACE*")
{
$v = New-Object PSObject
Add-Member -in $v NoteProperty "Provider Name" $provider.GetValue(0)
Add-Member -in $v NoteProperty "Description" $provider.GetValue(2)
$v
}
}

Related

Extract file names from a File Explorer search into Excel

This has been bugging me for while as I feel I have few pieces of the puzzle but I cant put them all together
So my goal is to be able to search all .pdfs in a given location for a keyword or phrase within the content of the files, not the filename, and then use the results of the search to populate an excel spreadsheet.
Before we start, I know that this easy to do using the Acrobat Pro API, but my company are not going to pay for licences for everyone so that this one macro will work.
The windows file explorer search accepts advanced query syntax and will search inside the contents of files assuming that the correct ifilters are enabled. E.g. if you have a word document called doc1.docx and the text inside the document reads "blahblahblah", and you search for "blah" doc1.docx will appear as the result.
As far as I know, this cannot be acheived using the FileSystemObject, but if someone could confirm either way that would be really useful?
I have a simple code that opens an explorer window and searches for a string within the contents of all files in the given location. Once the search has completed I have an explorer window with all the files required listed. How do I take this list and populate an excel with the filenames of these files?
dim eSearch As String
eSearch = "explorer " & Chr$(34) & "search-ms://query=System.Generic.String:" & [search term here] & "&crumb=location:" & [Directory Here] & Chr$(34)
Call Shell (eSearch)
Assuming the location is indexed you can access the catalog directly with ADO (add a reference to Microsoft ActiveX Data Objects 2.x):
Dim cn As New ADODB.Connection
Dim rs As New ADODB.Recordset
Dim sql As String
cn.Open "Provider=Search.CollatorDSO;Extended Properties='Application=Windows'"
sql = "SELECT System.ItemNameDisplay, System.ItemPathDisplay FROM SystemIndex WHERE SCOPE='file:C:\look\here' AND System.Kind <> 'folder' AND CONTAINS(System.FileName, '""*.PDF""') AND CONTAINS ('""find this text""')"
rs.Open sql, cn, adOpenForwardOnly, adLockReadOnly
If Not rs.EOF Then
Do While Not rs.EOF
Debug.Print "File: "; rs.Collect(0)
Debug.Print "Path: "; rs.Collect(1)
rs.MoveNext
Loop
End If
Try using the next function, please:
Function GetFilteredFiles(foldPath As String) As Collection
'If using a reference to `Microsoft Internet Controls (ShDocVW.dll)_____________________
'uncomment the next 2 lines and comment the following three (without any reference part)
'Dim ExpWin As SHDocVw.ShellWindows, CurrWin As SHDocVw.InternetExplorer
'Set ExpWin = New SHDocVw.ShellWindows
'_______________________________________________________________________________________
'Without any reference:_____________________________________
Dim ExpWin As Object, CurrWin As Object, objshell As Object
Set objshell = CreateObject("Shell.Application")
Set ExpWin = objshell.Windows
'___________________________________________________________
Dim Result As New Collection, oFolderItems As Object, i As Long
Dim CurrSelFile As String
For Each CurrWin In ExpWin
If Not CurrWin.Document Is Nothing Then
If Not CurrWin.Document.FocusedItem Is Nothing Then
If left(CurrWin.Document.FocusedItem.Path, _
InStrRev(CurrWin.Document.FocusedItem.Path, "\")) = foldPath Then
Set oFolderItems = CurrWin.Document.folder.Items
For i = 0 To oFolderItems.count
On Error Resume Next
If Err.Number <> 0 Then
Err.Clear: On Error GoTo 0
Else
Result.Add oFolderItems.item(CLng(i)).Name
On Error GoTo 0
End If
Next
End If
End If
End If
Next CurrWin
Set GetFilteredFiles = Result
End Function
Like it is, the function works without any reference...
The above function must be called after you executed the search query in your existing code. It can be called in the next (testing) way:
Sub testGetFilteredFiles()
Dim C As Collection, El As Variant
Set C = GetFilteredFiles("C:\Teste VBA Excel\")'use here the folder path you used for searching
For Each El In C
Debug.Print El
Next
End Sub
The above solution iterates between all IExplorer windows and return what is visible there (after filtering) for the folder you initially used to search.
You can manually test it, searching for something in a specific folder and then call the function with that specific folder path as argument ("\" backslash at the end...).
I've forgotten everything I ever knew about VBA, but recently stumbled across an easy way to execute Explorer searches using the Shell.Application COM object. My code is PowerShell, but the COM objects & methods are what's critical. Surely someone here can translate.
This has what I think are several advantages:
The query text is identical to what you wouold type in the Search Bar in Explorer, e.g.'Ext:pdf Content:compressor'
It's easily launched from code and results are easily extracted with code, but SearchResults window is available for visual inspection/review.
With looping & pauses, you can execute a series of searches in the same window.
I think this ability has been sitting there forever, but the MS documentation of the Document object & FilterView method make no mention of how they apply to File Explorer.
I hope others find this useful.
$FolderToSearch = 'c:\Path\To\Folder'
$SearchBoxText = 'ext:pdf Content:compressor'
$Shell = New-Object -ComObject shell.application
### Get handles of currenlty open Explorer Windows
$CurrentWindows = ( $Shell.Windows() | Where FullName -match 'explorer.exe$' ).HWND
$WinCount = $Shell.Windows().Count
$Shell.Open( $FolderToSearch )
Do { Sleep -m 50 } Until ( $Shell.Windows().Count -gt $WinCount )
$WindowToSerch = ( $Shell.Windows() | Where FullName -match 'explorer.exe$' ) | Where { $_.HWND -notIn $CurrentWindows }
$WindowToSearch.Document.FilterView( $SearchBoxText )
Do { Sleep -m 50 } Until ( $WindowToSearch.ReadyState -eq 4 )
### Fully-qualified name:
$FoundFiles = ( $WindowToSearch.Document.Folder.Items() ).Path
### or just the filename:
$FoundFiles = ( $WindowToSearch.Document.Folder.Items() ).Name
### $FoundFIles is an array of strings containing the names.
### The Excel portion I leave to you! :D

Connection from VBA to Oracle DB

With setup from text below I successfully connected and retrieve data from DB. One time, while macro was executing, my PC (windows 10) lost the power and from that moment on I'm receiving the error every time I tried to connect to DB (only while I'm trying to connect via VBA) with following message:Run-time error '-2147467259 (80004005)':[Microsoft][ODBC driver for Oracle][Oracle]Error while trying to retrieve text for error ORA-01019Error that I received is from the line with command "cn.Open (strConnection)"I have installed ODAC 12c 32bit because I have Excel 32bit.I think that this error is active because of info from some register which is locked after PC lost the power while retrieving data but I can't find it.Any help or hint will be precious to me.Thanks in advance
Configuration is:Environment Variables:ORACLE_HOME = C:\app\client\xxxx\product\12.2.0\client_1PATH = C:\app\client\xxxx\product\12.2.0\client_1\Network\AdminPATH = C:\app\client\xxxx\product\12.2.0\client_1\Network\Admin\binReferences - VBAProject:Visual Basic for ApplicationsMicrosoft Excel 16.0 Object LibraryMicrosoft Forms 2.0 Object LibraryMicrosoft ActiveX Data Objects 2.8 LibraryMicrosoft ActiveX Data Object Recordset 2.8 LibraryMicrosoft OLE DB Simple Provider 1.5 LibraryOraOLEDB 1.0 Type LibraryActive Services:OracleOraClient12Home1_32bitMTSRecoveryServiceI tried to uninstall Oracle Client and install it again, but with no success. Also I created ORACLE_HOME variable and tried more different variants of connection string and combination of included References but error is still the same.
Dim strConneciton As String
Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Set cn = New ADODB.Connection
Set rs = New ADODB.Recordset
strConneciton = "Driver={Microsoft ODBC for Oracle};" & _
"CONNECTSTRING=(DESCRIPTION=" & _
"(ADDRESS=(PROTOCOL=TCP)" & _
"(HOST=xxx.xxxx.xxx)(PORT=1521)" & _
"(CONNECT_DATA=(SERVICE_NAME=xxxxx)));user id=user1;password=1234;")
cn.Open (strConneciton)
If cn.State = adStateOpen Then
cn.Close
MsgBox "Completed!"
Else
MsgBox "Connection failed!"
End If
I've been struggling with the same connectivity error. Here's how it worked for me.
This is an extract of my tnsnames.ora:
#VISUALTIME7 / EX PRODUCTION
VISUALTIME7_DEV=
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = XXX.XX.XX.XX)(PORT = XXXX))
)
(CONNECT_DATA =
(SERVICE_NAME = VISUALTIME7)
)
)
This is my vba code:
Sub CopyDataFromDatabase()
Dim Conn As ADODB.Connection
Set Conn = New ADODB.Connection
Dim strCon As String
'DataSource argument according to my tnsnames.ora
strCon = "Provider=OraOLEDB.Oracle;Data Source=VISUALTIME7_DEV;User ID=myUser;Password=myPassword;"
Conn.Open (strCon)
Conn.Close
End Sub
My references in vba project:
Visual Basic For Applications
Microsoft Excel 10.0 Object Library
OLE Automation
Microsoft Office 16.0 Object Library
Microsoft ActiveX Data Objects 6.1 Library
Thanks for answers.I added those locations to the PATH variable, but the problem is the same.With change of a driver (Oracle in OraClient12Home1_32bit - which is correct name in ODBC Data Source Administrator (32bit)), I've got the following error: TNS protocol adapter error.I am able to connect from sqlplus to db, but the problem is when I tried to connect via VBA.#Tim, thanks for that hint, but that is not the problem here, I've checked that before.Finally I finished this with new Connection string as you can see below:strConnection = "Provider=OraOLEDB.Oracle;Data Source=xxx.xxxx.xxx:1521/xxxxx;User ID=user1;Password=1234;"Thanks again.

MS Access Nz() Function not Recognised in MS Excel

I'm trying to write an expression in MS Access which returns a string of text, "New Policy", in the Iif() statement after it returns an error.
When I export the data from Access into Excel it tells me that Nz() is not recognised.
Is there an alternative to this function? My Access expression is as follows:
Nz(IIf([Policy Status]=[Input - WFAC Previous Day]![Policy Status 1],"Remains " & [Policy Status],[Input - WFAC Previous Day]![Policy Status 1] & " to " & [Policy Status]), "New Policy")
Nz is defined in the Microsoft Access type library, which is automatically referenced when your host application is, well, Access.
If you add a reference to the Access type library in your Excel project, you should be able to use Nz... but then your Excel project won't work if Access isn't installed, which is... weird and rather heavy-handed.
What does Nz do? Looks like some kind of Coalesce function that should be rather trivial to implement on your own and customize as needed. Something like this?
Public Function Coalesce(ByVal value As Variant, Optional ByVal value_when_null As Variant = 0) As Variant
Dim return_value As Variant
On Error Resume Next 'supress error handling
If IsEmpty(value) Or IsNull(value) Or (VarType(value) = vbString And value = vbNullString) Then
return_value = value_when_null
Else
return_value = value
End If
Err.Clear 'clear any errors that might have occurred
On Error GoTo 0 'reinstate error handling
Coalesce = return_value
End Function
You don't need Nz for this:
IIf(IsNull([Policy Status]), "New Policy",
IIf([Policy Status] & "" = [Input - WFAC Previous Day]![Policy Status 1],
"Remains " & [Policy Status],
[Input - WFAC Previous Day]![Policy Status 1] & " to " & [Policy Status]))
If you're using VBA, you can add a Reference to the MS Access library, e.g. "Microsoft Access 14.0 object library. Then the Nz function is available as Access.Nz(value, "New Policy"). You could even create a user-defined function for use on Excel spreadsheets:
Public Function Nz(Value As Variant, Optional ValueIfNull As Variant = "New Policy") As Variant
Nz = Access.Nz(Value, ValueIfNull)
End Function
Hope that helps

Import Data from Access using JET SQL (having a Custom Function)

I have an MS access 2010 database which is connected to a MS Excel 2010 for reporting purpose. I have linked the Excel to Access using Get External Data option in excel. With few changes in the reporting requirements I had to create a new query in Access (and it has some custom function). The Custom Function is a VBA module in Access.
Unfortunately when I use the Get External Data in Excel to link my new access query, the new query (View) is not listed on the list of Table/View (Import Wizard). When I remove the Custom Function the query is displayed in the wizard.
My Custom Function to Concatenate rows (taken from another site)
Public Function ConcatADO(strSQL As String, strColDelim, _
strRowDelim, ParamArray NameList() As Variant)
Dim rs As New ADODB.Recordset
Dim strList As String
On Error GoTo Proc_Err
If strSQL <> "" Then
rs.Open strSQL, CurrentProject.Connection
strList = rs.GetString(, , strColDelim, strRowDelim)
strList = Mid(strList, 1, Len(strList) - Len(strRowDelim))
Else
strList = Join(NameList, strColDelim)
End If
ConcatADO = strList
Exit Function
Proc_Err:
ConcatADO = "***" & UCase(Err.Description)
End Function
and following is the JET SQL used in the new query (which works absolutely fine within Access)
SELECT DISTINCT
D.[Ref ID],
D.[ENTRYDATE],
D.[AUDITOR LID],
D.[Process],
D.[Auditee],
D.[Auditee Name],
D.[Account No],
D.[Auditee Manager],
D.[MaxScore],
D.[Score],
D.[Result],
ConcatADO("SELECT [COMMENTS] FROM ycube WHERE [Ref ID]=" & "'" & [d].[Ref ID] & "'" ,", "," : ") AS [Master Comment]
FROM ycube AS D;
Is it the limitation of Excel when we use Custom Function and
Is there a way around to import (rather link) above Access query to Excel

classic ASP Microsoft OLE DB Provider for ODBC Drivers error '80004005'

I'm working on migrating an application from an IIS 6 to IIS 7.5 and am running into the weirdest issue:
Microsoft OLE DB Provider for ODBC Drivers error '80004005'
[Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified
/Complaints/Login.asp, line 175
Here's the code around line 175:
myConn = getDatabaseConnection()
set rs = Server.CreateObject("ADODB.Recordset")
strSQL = "SELECT * FROM Users WHERE lower(Login) = lower('" & uId & "') and Active = 1"
rs.Open strSQL, myConn, 3, 3
Nothing special going on here...
here's the db method:
function getDatabaseConnection()
Dim strConnection
strConnection = "Driver={SQL Server};Server=server.domain.com;Database=cc;uid=acc;pwd=xxx;"
Set GetDatabaseConnection = Server.CreateObject("ADODB.Connection")
GetDatabaseConnection.CommandTimeout = 60
GetDatabaseConnection.ConnectionTimeout = 60
GetDatabaseConnection.CursorLocation = 3
GetDatabaseConnection.Open strConnection
end function
This seems to work in a similar classic asp application running in the same app pool (.NET 1.1)
I've tried: copy pasting the other app's code, using the connection string in place of the db method (throws 500 of course), changing app pools, google, & as another kick it works great on an IIS 6 server.
I took a look at OLE DB Provider for ODBC Drivers Error "80004005' & my connection string seems correct & my ASP.NET 1.1 app pool can only run in 32-bit mode. The DSNs set up on the previous server aren't relevant either.
I have the application working on IIS 5 on domain A and IIS 6 on domain A, but this 7.5 server is on domain B. Thus I'm using the FQDN. I haven't made any other domain specific changes though. The system uses the above method to authenticate users.
Edit: also tried
strConnection = "dsn=my32bitdsn;uid=xxx;pwd=xxx;"
I've inherited this code and am so so with classic ASP, can anybody help?
Updated code:
Dim strConnection, oConn
'get status
set rs = Server.CreateObject("ADODB.Recordset")
strSQL = "SELECT * FROM Users WHERE lower(Login) = lower('" & uId & "') and Active = 1"
'rs.Open strSQL, myConn, 3, 3
strConnection = "Driver={SQL Server};Server=server.domain.com;Database=cc;uid=acc;pwd=xxx;"
Set oConn = Server.CreateObject("ADODB.Connection")
oConn.CommandTimeout = 60
oConn.ConnectionTimeout = 60
oConn.CursorLocation = 3
oConn.Open strConnection
Set rs = oConn.Execute(strSQL)
Might be just cosmetic change, but might solve that issue as well:
Function getDatabaseConnection()
Dim strConnection, oConn
strConnection = "Driver={SQL Server};Server=server.domain.com;Database=cc;uid=acc;pwd=xxx;"
Set oConn = Server.CreateObject("ADODB.Connection")
oConn.CommandTimeout = 60
oConn.ConnectionTimeout = 60
oConn.CursorLocation = 3
oConn.Open strConnection
Set getDatabaseConnection = oConn
End Function
I'm always afraid that using the function name directly will result in unneeded calls or weird results so got used to the above way.
Second thing is that you assign the connection as non object by not having "Set" which also might cause weird and unexpected problems. Change the line to:
Set myConn = getDatabaseConnection()
Hopefully one of the above will solve that weird problem.
I am not sure if you have already solved this error, but if you would like to try and get it to throw a readable error you can try this as part of the connection string.
Your connection string says the db server is server.domain.com or did you just place that there to replace your companies information?
Give this a try:
dim cn
Set cn=Server.CreateObject("ADODB.Connection")
cn.ConnectionString="Provider=SQLOLEDB.1;Persist Security Info=True;User ID=sa;Initial Catalog=dbName;Data Source=(local) or computername;PWD=;Password=yourpassword;"
on error resume next
cn.Open
if err.number <> 0 then response.Write(err.description)
on error goto 0

Resources