Forum Discussion

Lucian's avatar
Lucian
Responsive Resident
6 years ago
Solved

Formula.Firewall Error in combination with PowerQuery function

Hello,

 

I am trying to create a "dynamic union" of identical tables from a Navision database.  Basicaly I need come "consolidated data" without using the Consolidated company from NAV.

These tables are using the followig rule: CompanyName$TableName. 

I have created a PowerQuery function (GetProjectsTable) that will load for example the Projects table (the same principle will be used for other tables too):

 

(strCompanyName as text) as table =>
let
    strTableName=strCompanyName&"$Projects",
    Source = Sql.Databases(NAVDataURL),
    srcDBName = Source{[Name=NAVDBName]}[Data],
    #"tblProjects" = srcDBName{[Schema="dbo",Item=strTableName]}[Data],
    #"Removed Other Columns" = Table.SelectColumns(#"tblProjects",{"Code", "Description", "Starting date", "Ending Date", "Sales person Code", "Project Type"})
in
    #"Removed Other Columns"

 

With another query (Company) I get the company names for which I will need the "consolidated tables" (similar with union):

 

let
    Source = Sql.Databases(NAVDataURL),
    DBSource = Source{[Name=NAVDBName]}[Data],
    dbo_Company = DBSource{[Schema="dbo",Item="Company"]}[Data],
    #"Removed Columns" = Table.RemoveColumns(dbo_Company,{"timestamp", "Evaluation Company"}),
    #"Filtered Rows" = Table.SelectRows(#"Removed Columns", each ([Name] = "Comp1" or [Name] = "Comp2"))
in
    #"Filtered Rows"

 

This query will return a single column table:

Comp1

Comp2

 

To create the ALLProjects table I would like to "reference" directly the Company query because this would be filtered depending on some criteria and the same list would be used to generate an ALLTableName. Based on the referenced query, I add a new column invoking the custom function that should return the proper table for each company.

 

So I have tryied this query:

 

let
    Source = Company,
    #"Invoked Custom Function" = Table.AddColumn(Source, "GetProjectsTable", each GetProjectsTable([Name]))
in
    #"Invoked Custom Function"

 

But this approach would result in the following error:

 

Formula.Firewall: Query 'Company (2)' (step 'Invoked Custom Function') references other queries or steps, so it may not directly access a data source. Please rebuild this data combination.

 

Another approach was to "duplicate" the Company query - this way is more like an "independent copy" and now adding the column invoking the custom function to get the tables will work.

 

let
    Source = Sql.Databases(NAVDataURL),
    DBSource = Source{[Name=NAVDBName]}[Data],
    dbo_Company = DBSource{[Schema="dbo",Item="Company"]}[Data],
    #"Removed Columns" = Table.RemoveColumns(dbo_Company,{"timestamp", "Evaluation Company"}),
    #"Filtered Rows" = Table.SelectRows(#"Removed Columns", each ([Name] = "Comp1" or [Name] = "Comp2")),
    #"Invoked Custom Function" = Table.AddColumn(#"Filtered Rows", "GetProjectsTable", each GetProjectsTable([Name])),
    #"Expanded GetProjectsTable" = Table.ExpandTableColumn(#"Invoked Custom Function", "GetProjectsTable", {"Code", "Description", "Starting date", "Ending Date", "Sales person Code", "Project Type"}, {"Code", "Description", "Starting date", "Ending Date", "Sales person Code", "Project Type"})
in
    #"Expanded GetProjectsTable"

 

But using this approach if the filter would change, I have to manually change each query that would get the tables.

 

Is there a way to get a "list" that could be "referenced" in other queries that will invoke some functions that return tables that would be expanded without bumping into "Formula.Firewall Error"?...

 

Kind Regards,

Lucian

  • try to "functionize" the Company-query like so: (adding " () => " at the start)

     

    () =>
    let
        Source = Sql.Databases(NAVDataURL),
        DBSource = Source{[Name=NAVDBName]}[Data],
        dbo_Company = DBSource{[Schema="dbo",Item="Company"]}[Data],
        #"Removed Columns" = Table.RemoveColumns(dbo_Company,{"timestamp", "Evaluation Company"}),
        #"Filtered Rows" = Table.SelectRows(#"Removed Columns", each ([Name] = "Comp1" or [Name] = "Comp2"))
    in
        #"Filtered Rows"

     

    and then call it like so: Company() 
    This is a function without a parameter, but you have to include the parenthesis.

     

    let
        Source = Company(),
        #"Invoked Custom Function" = Table.AddColumn(Source, "GetProjectsTable", each GetProjectsTable([Name]))
    in
        #"Invoked Custom Function"

     

9 Replies

    • Lucian's avatar
      Lucian
      Responsive Resident

      Hi Greg_Deckler ,

       

      I would like to thank you for the replies on other posts... but for this one I have a problem reading it... 😁

      Could you please post it again?

       

      Kind Regards,

      Lucian

      • Greg_Deckler's avatar
        Greg_Deckler
        Community Champion

        Oh, sorry, that is probably because that post was really, really short. I was just "invoking ImkeF ". She is one of, if not the best, Power Query person out there so when I find a Power Query question that I can't answer, I call her attention to it by mentioning her.