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?
问题:
回答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.
回答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
回答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.