Is there a way to get ADODB to work with Excel for Mac 2011?

11,702

Solution 1

Are there add-ins available? Even from a third-party?

Hope these download links helps?

ODBC drivers that are compatible with Excel for Mac


Quoted from the MSKB in case the link dies

ODBC drivers that are compatible with Excel for Mac

If you want to import data into Excel for Mac from a database, you need an Open Database Connectivity (ODBC) driver installed on your Mac. The driver you get depends on which version of Excel for Mac you have.

Excel for Mac 2011

This version of Excel does not provide an ODBC driver. You must install it yourself. Drivers that are compatible with Excel for Mac 2011 are available from these companies:

OpenLink Software

Actual Technologies

Simba Technologies

After you install the driver for your source, you can use Microsoft Query to create new queries or refresh existing queries that were created in other versions of Excel, such as Excel X, Excel 2004, and Excel for Windows. For more information, see Import data from a database in Excel for Mac 2011.

Excel 2016 for Mac

This version of Excel does provide an ODBC driver for connecting to SQL Server Databases. On the Data tab, click New Database Query > SQL Server ODBC. Then use the dialog boxes to import the data.

If you are connecting to other ODBC data sources (for example, FileMaker Pro), then you'll need to install the ODBC driver for the data source on your Mac. Drivers that are compatible with Excel for Mac are available from these companies:

OpenLink Software

Actual Technologies

Has anyone gotten this to work?

Sorry, I have never used it.

Solution 2

ADODB is NOT supported in Mac Excel 2011, but ODBC works in conjunction with a 3rd party driver.

I got my ODBC drivers from ActualTech. Download and install their program and you'll have the necessary drivers for connecting to SQL servers and databases (Free to try, $35 to purchase).

The following code creates a connection to a mySQL database, and returns information from the database into Cell A1:

Dim connstring as String
Dim sqlstring as String

connstring = "ODBC;DRIVER={Actual Open Source Databases};" _
& "SERVER=<server_location>;DATABASE=<database>;" _
& "UID=<userID>;PWD=<password>;Port=3306"
sqlstring = "select * from <database_table>"

With ActiveSheet.QueryTables.Add(Connection:=connstring, Destination:=Range("A1"), Sql:=sqlstring)
  .BackgroundQuery = False
  .Refresh
End With

Solution 3

There are 2 pieces to getting Mac Excel to query MySQL: (1) the VBA and (2) the ODBC driver.


(1) The VBA for creating a table from a query (and updating it with a new query):

Option Explicit

Sub WaitQueryTableRefresh(ByVal qt As QueryTable)
    While qt.Refreshing
        Application.Wait (Now + TimeValue("0:00:01"))
    Wend
End Sub

Sub ErrorIfQueryTableOverflowed(ByVal qt As QueryTable)
    If qt.FetchedRowOverflow Then
        err.Raise 5, "ErrorIfQueryTableOverflowed", _
            "QueryTable '" & qt.ListObject.Name & "' returned more rows than can fit in the spreadsheet range"
    End If
End Sub

' Create a table from scratch
Function CreateTableFromSql( _
 ByVal table_sheet As Worksheet, _
 ByVal table_range As Range, _
 ByVal table_name As String, _
 ByVal sql As String _
 ) As ListObject
    ' table_range is simply the top-left, corner cell for the table

    'ListObject.SourceType
        'https://docs.microsoft.com/en-us/dotnet/api/microsoft.office.interop.excel.xllistobjectsourcetype?view=excel-pia

    'QueryTable.CommandType
        'https://docs.microsoft.com/en-us/office/vba/api/Excel.QueryTable.CommandType

    'QueryTable.BackgroundQuery
        'https://docs.microsoft.com/en-us/office/vba/api/excel.querytable.backgroundquery

    'QueryTable.RefreshStyle
        'https://docs.microsoft.com/en-us/office/vba/api/excel.xlcellinsertionmode

    'QueryTable.PreserveColumnInfo
        'https://stackoverflow.com/a/28621172
        'https://docs.microsoft.com/en-us/office/vba/api/Excel.QueryTable.PreserveColumnInfo

    Dim global_odbc_str As String
    global_odbc_str = "ODBC;DSN=my_dsn_name;"

    Dim qt As QueryTable
    Set qt = table_sheet.ListObjects.Add( _
        SourceType:=xlSrcExternal, _
        Source:=global_odbc_str, _
        Destination:=table_range _
    ).QueryTable

    With qt
        .ListObject.Name = table_name
        .ListObject.DisplayName = table_name
        .CommandText = sql
        .RowNumbers = False
        .FillAdjacentFormulas = False
        .PreserveFormatting = True
        .RefreshOnFileOpen = False
        .BackgroundQuery = False
        .RefreshStyle = xlInsertDeleteCells
        .SavePassword = False
        .SaveData = True
        .AdjustColumnWidth = True
        .RefreshPeriod = 0
        .PreserveColumnInfo = False
        .Refresh BackgroundQuery:=False
    End With

    Call WaitQueryTableRefresh(qt)
    Call ErrorIfQueryTableOverflowed(qt)

    Set CreateTableFromSql = qt.ListObject
End Function

' Update a table (columns do not have to be the same)
Sub UpdateTableFromSql( _
 ByVal table As ListObject, _
 ByVal sql As String _
 )
    Dim qt As QueryTable
    Set qt = table.QueryTable

    qt.CommandText = sql
    qt.Refresh BackgroundQuery:=False

    Call WaitQueryTableRefresh(qt)
    Call ErrorIfQueryTableOverflowed(qt)
End Sub

(2) Configuring the MySQL ODBC driver (free)

Install according to MySQL docs:

(a) Install (dependency) iODBC Admin: http://www.iodbc.org/dataspace/doc/iodbc/wiki/iodbcWiki/Downloads

(b) Install MySQL ODBC driver: https://dev.mysql.com/downloads/connector/odbc/

(c) Mac requires all apps (including Excel) to be quarantined to a sandbox. Because of this, you need to relocate the MySQL driver to a place where Excel can access it. The symptom of failing to do this is that the DSN connection will Test successfully in iODBC but will fail to Test in Excel's ODBC.

Relocate the driver according to this:

#!/bin/bash

# https://github.com/openlink/iODBC/issues/29
# https://bugs.mysql.com/bug.php?id=89931

base_src_dir="/usr/local"
mysql_odbc_name=$(ls "$base_src_dir" | grep -m 1 "mysql-connector-odbc")
odbc_dir="/Library/ODBC"

src="$base_src_dir/$mysql_odbc_name/lib"
dst="$odbc_dir/$mysql_odbc_name/lib"

echo "creating '$dst'"
sudo mkdir -p "$dst"

echo "copying '$src' to '$dst'"
sudo cp -af "$src/." "$dst"


odbc_ini_path="$odbc_dir/odbc.ini"
odbc_ini_bak_path="$odbc_ini_path.bak"

odbcinst_ini_path="$odbc_dir/odbcinst.ini"
odbcinst_ini_bak_path="$odbcinst_ini_path.bak"

echo "backing up '$odbc_ini_path' to '$odbc_ini_bak_path'"
sudo cp -f "$odbc_ini_path" "$odbc_ini_bak_path"

echo "backing up '$odbcinst_ini_path' to '$odbcinst_ini_bak_path'"
sudo cp -f "$odbcinst_ini_path" "$odbcinst_ini_bak_path"

# https://stackoverflow.com/a/29626460
function replace {
  sudo sed -i '' "s/$(sed 's/[^^]/[&]/g; s/\^/\\^/g' <<< "$1")/$(sed 's/[&/\]/\\&/g' <<< "$2")/g" "$3"
}

ansi_driver=$(ls "$dst" | grep -m 1 "^lib.*a\.so$")
unicode_driver=$(ls "$dst" | grep -m 1 "^lib.*w\.so$")

old_ansi_path="$src/$ansi_driver"
new_ansi_path="$dst/$ansi_driver"

old_unicode_path="$src/$unicode_driver"
new_unicode_path="$dst/$unicode_driver"

echo "updating '$old_ansi_path' to '$new_ansi_path' in '$odbc_ini_path'"
replace "$old_ansi_path" "$new_ansi_path" "$odbc_ini_path"

echo "updating '$old_ansi_path' to '$new_ansi_path' in '$odbcinst_ini_path'"
replace "$old_ansi_path" "$new_ansi_path" "$odbcinst_ini_path"

echo "updating '$old_unicode_path' to '$new_unicode_path' in '$odbc_ini_path'"
replace "$old_unicode_path" "$new_unicode_path" "$odbc_ini_path"

echo "updating '$old_unicode_path' to '$new_unicode_path' in '$odbcinst_ini_path'"
replace "$old_unicode_path" "$new_unicode_path" "$odbcinst_ini_path"

The above was tested on High Sierra with Excel 2016.

Share:
11,702
n8gard
Author by

n8gard

Updated on August 09, 2022

Comments

  • n8gard
    n8gard over 1 year

    I can not seem to get my Excel workbook (using ADODB) to work with Excel Mac 2011. I am using ADODB code. Are there add-ins available? Even from a third-party? Has anyone gotten this to work?