Guest Post by Dany Hoter
After I published a post about manipulating relationships, Rob suggested that I take a step back and cover the entire scope of what’s possible with the object model.
Can you build a model from scratch? Can you add a new table to an existing table? Can you add calculated columns? What about calculated measures? , Can you change a connection for an existing table in the model?
The short answer to these questions is Yes, Yes, No, No, Yes
The longer version is the rest of this post. Everything in this post is NOT possible in Excel 2010 – this stuff works in 2013 only.
The object model consists of the following elements:
The only property that I found useful in this list is ModelRelationships collection which I used extensively in the previous post.
The ModelTables collection looks promising as it contains ModelTableColumns and could be the way to introduce new tables, new columns or even measures into the model. Unfortunately all these collections are read-only and cannot be used for adding to the model.
So how is still possible to add new tables or even to start a model from scratch?
It all has to do with the method add2 of the Connections collection.
This method can be used to add new tables to the data model from a variety of sources.
This is the definition of this method:
The two last Boolean parameters are related to adding connections to the data model.
I started by recording macros while importing data into Excel but I must admit that a lot of cleaning was needed after recording
If you use any of these examples on an empty workbook, a data model will be created, the table(s) will be added to it and if relevant also relationships between the imported tables will be added.
So if you run this specific example that imports data from an OData feed available on the web it should always work:
Sub TwotablesFromOData()
ActiveWorkbook.Connections.Add2 _
“DataFeed_2_services-odata-org Multiple Tables”, “”, _
“DATAFEED;Data Source=https://services.odata.org/northwind/northwind.svc/;Namespaces to Include=*;Max Received Message Size=4398046511104;Integrated Security=SSPI;Keep Alive=true;Persist Security Info=false;Service Document Url=https://services.odata.org/northwind/northwind.svc/” _
, “””Order_Details””,””Orders”””, 6, True, False
End Sub
Creating from SQL server source instead
Creating from a Table
Sub AddSQLtables()
‘One or more tables from a SQL server database
‘Relationships are detected if they are declared in the database
ActiveWorkbook.Connections.Add2 _
“Connection Name”, “”, _
“OLEDB;Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=True;Data Source=<SQL server – name>;Use Procedure for Prepare=1;Auto Translate=True;Packet Size=4096;Use Encryption for Data=False;Tag with column collation when possible=False;Initial Catalog=AdventureWorksDW2008R2” _
, “””DimCustomer””,””DimGeography”””, 6, True, True
End Sub
Parameters need to be adjusted to your needs of course like server name, database and tables.
Notice the list of tables with the multiple quotes around them. You can include one or more tables or views. You can’t specify a subset of columns from a table.
The two True values tell Excel to add the tables to the model and to detect relationships.
Relationships between the table imported together are detected and if they exist they are added to the ModelRelationships collection
Creating from a SQL query
Sub Addsql()
‘A SQL query is used to create a table in the model.
‘ The table name cannot be changed and is <database name query>
‘
ActiveWorkbook.Connections.Add2 _
“All fields from customer”, “”, _
“OLEDB;Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=True;Data Source=<SQL server – name>;Use Procedure for Prepare=1;Auto Translate=True;Packet Size=4096;Use Encryption for Data=False;Tag with column collation when possible=False;Initial Catalog=AdventureWorksDW2008R2” _
, “select * from “”DimCustomer”””, 2, True, True
End Sub
I couldn’t find a way to determine the name of the new table in the model L
Creating from Access tables
Sub AccessTables()
‘A collection of tables from Access. Relationships are detected
ActiveWorkbook.Connections.Add2 “Sales Retail”, “”, Array( _
“OLEDB;Provider=Microsoft.ACE.OLEDB.12.0;Password=””””;User ID=Admin;Data Source=C:\Users\danyh\Documents\Sales Retail.accdb;Mode=Share D” _
, _
“eny Write;Extended Properties=””””;Jet OLEDB:System database=””””;Jet OLEDB:Registry Path=””””;Jet OLEDB:Database Password=””””;Jet OLED” _
, _
“B:Engine Type=6;Jet OLEDB:Database Locking Mode=0;Jet OLEDB:Global Partial Bulk Ops=2;Jet OLEDB:Global Bulk Transactions=1;Jet O” _
, _
“LEDB:New Database Password=””””;Jet OLEDB:Create System Database=False;Jet OLEDB:Encrypt Database=False;Jet OLEDB:Don’t Copy Local” _
, _
“e on Compact=False;Jet OLEDB:Compact Without Replica Repair=False;Jet OLEDB:SFP=False;Jet OLEDB:Support Complex Data=False;Jet O” _
, _
“LEDB:Bypass UserInfo Validation=False;Jet OLEDB:Limited DB Caching=False;Jet OLEDB:Bypass ChoiceField Validation=False” _
), “””Employees””,””departments”””, 6, True, True
Probably many parameters are optional. Again the main thing are the two last parameters which add the tables to the model and trigger relationships detection.
From a CSV file
Sub FromCsv()
ActiveWorkbook.Connections.AddFromFile _
“C:\Users\danyh\Documents\MyTable.csv”, True, False
End Sub
This example is using a different method but the last two parameters are the same
From a table in the same file
Sub FromTable()
ActiveWorkbook.Connections.Add2 _
“WorksheetConnection_Import tables.xlsm!TableName”, “”, _
“WORKSHEET;C:\Users\danyh\Documents\Import tables.xlsm”, _
“Import tables.xlsm!TableName”, 7, True, False
End Sub
From ODATA feed
Sub TwotablesFromOData()
ActiveWorkbook.Connections.Add2 _
“DataFeed_2_services-odata-org Multiple Tables”, “”, _
“DATAFEED;Data Source=https://services.odata.org/northwind/northwind.svc/;Namespaces to Include=*;Max Received Message Size=4398046511104;Integrated Security=SSPI;Keep Alive=true;Persist Security Info=false;Service Document Url=https://services.odata.org/northwind/northwind.svc/” _
, “””Order_Details””,””Orders”””, 6, True, False
End Sub