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:

clip_image001

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:

image

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 Smile

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