Getting "Please rebuild this data combination" on a computer but not on another one - excel

This is my first try at using the Power Query... I've build a "dynamic" query in which I can change the retrieved fields as well as the filtering fields and values to be used by the query.
It's working perfectly on my computer but as soon as I try to execute it on another computer, I get the "Please rebuild this data combination" error. I saw some post saying I'll have to kind of split my query but I have not been able to figure it out.
Here is what my 2 tables look like:
Condition and fields selection
and here is my Query with the error:
Query
This might not be very elegant, but it allow me, thru a VBA script, to generate the list of fields to be retrieved and to generate the condition to be used by the SQL.
Any idea why it's not working on the other computers or how to improved the solution I'm using?
Thank you!
Notes:
Hi, all my Privacy Level are already set to 'None'.
I've tried to parametrize my code but I can't figure how. The Where condition is dynamic: it could be Where Number = "1234" but in other condition, the where might be like: 'Where Assignee = "xyz"'.
Here is a simplified example of my code:
let
Source = Sql.Database("xxxx", "yyyy", [Query=
"Select network, testid
from CM3T1M1 "
& paramConditions[Conditions]{0} &
" "])
in
Source

rebuild query, Formula.Firewall
That's a feature to prevent prevent accidentally leaking data. You can change the privacy level to ignore it
See also: docs.microsoft/dataprivacyfirewall
Is the dynamic query inserting those cells into the SQL query ? Report Parameters are nice for letting the user change variables without having to re-edit the query.
Parameterized native SQL queries
from: https://blog.crossjoin.co.uk/2016/12/11/passing-parameters-to-sql-queries-with-value-nativequery-in-power-query-and-power-bi/
let
Source = Sql.Database("localhost", "Adventure Works DW"),
Test = Value.NativeQuery(
Source,
"SELECT * FROM DimDate
WHERE EnglishMonthName=#MonthName AND
EnglishDayNameOfWeek=#DayName",
[
MonthName = "March",
DayName = "Tuesday"
]
)
in
Test
Dynamic Power Query version of SQL Query
To dynamically generate this SQL Query
select NUMBER, REQUESTED_BY from SourceTable
where NUMBER = 404115
Table.SelectRows is your Where.
SelectColumns is your select
let
Source = ...,
filterByNum = 404115,
columnNames = {"NUMBER", "REQUESTED_BY"},
removedColumns = Table.SelectColumns(
Source, columnNames, MissingField.Error
),
// I used 'MissingField.Error' so you know right away
// if there's a typo or bug
// assuming you are comparing Source[NUMBER]
filteredTable = Table.SelectRows(
Source, each [NUMBER] = filterByNum
)
in
filteredTable

Related

Powerquery - reference Excel cell value within SQL query?

I am trying to modify an excel worksheet that was given to me, with a connection to a SQL database that looks as follows:
select * from DB.AccountAssignments where Company_Code = '102'
How can I replace the static 102 value to reference a specific cell in Excel? For example, cell A1? The objective of course, being that when I change the 102 for a different value, the query will re-run without having to enter PowerQuery to edit the query it self each time.
NOTE: I found examples that involve filtering AFTER the query runs and pulls the data. However, the data source is HUGE so I need the Company Code parameter to be embedded within the query, so that the data brought into Powerquery is already filtered. That makes the difference between the query taking 5 seconds to run to 5 minutes to run.
I spent a couple hours attempting instructions on older posts, but have not been successful so far.
I had the same problem and it took me some time to understand how to implement Sharif's answer. So here are more detailed instructions based on the same idea:
Convert your cell into a named range (Formulas > Define Name)
Select the cell and go to Data > Get Data > From Other Sources > From Table/Range, which opens the Power Query Editor
Right-click on your cell value in the little preview table in the editor and select 'Drill Down'
Go to Home/File > Close & Load To (the 'To' is important here!). An 'Import Data' window pops up. Select 'Only create connection'.
Now you have a query parameter, that can be used in any other query.
Open the power query editor for your SQL query (Edit)
User the parameter in your query:
Source = Odbc.Query("dsn=SQLDSN", "select * from DB.AccountAssignments where Company_Code = " & NamedRangeCompanyCodeFromCell )
I got the error Expression.Error: We cannot apply operator & to types Text and Number. I solved that by changing the type of my query parameter: In the query of my parameter under Applied Steps > Changed Type, I changed Int64.Type to type text
Most likely, you will also need to give permission to run this query
Instead of creating a separate query parameter, it can also be created on the fly within the SQL query:
Open the Power Query Editor of your SQL query (Edit)
Open the advanced editor (Home > Advanced Editor)
Do all the necessary steps here, e.g.:
let
Params = Excel.CurrentWorkbook(){[Name="myNamedRange"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Params,{{"Column1", type text}}),
CodeFromCell = #"Changed Type"{0}[Column1],
Source = Odbc.Query("dsn=SQLDSN", "select * from DB.AccountAssignments where Company_Code = " & CodeFromCell)
in
Source
Convert cell A1 to Table from Range (Insert -> Table)
Name the table as param (or anything you like)
Use the below lines to use this table in your power query:
params = Excel.CurrentWorkbook(){[Name="params"]}[Content],
code = params{0}[value],
Use this in your SQL query:
select * from DB.AccountAssignments where Company_Code = code
Most likely you will have something similar to below line in your power query editor:
Source = Odbc.Query("dsn=SQLDSN", "select * from DB.AccountAssignments where Company_Code = " & code ),

Kentico Repeater with Custom Query

OK Here we go.
Using Kentico 11/Portal Engine (no hot fixes)
Have a table that holds Content only page Types. One field of importance is a Date and time field.
I am trying to get rows out of this table that match a certain month and year criteria. For instance give me all records where Month=2 and Year=2018. These argument will be passed via the query string
I have a custom Stored proc that I would like to receive two int(or string) arguments then return a collection of all matching rows.
I am using a RepeaterWithCustomQuery to call the procedure and handle the resulting rows. As you can see below the querystring arguments are named "year" and "monthnumber".
The Query
Me.PR.PREDetailSelect
When my Webpart is set up in this configuration I get the following error:
In my Query, I have tried:
EXEC Proc_Custom_PRDetails #MonthNumber = ##ORDERBY##; #Year = ##WHERE##<br/>
EXEC Proc_Custom_PRDetails #MonthNumber = ##ORDERBY##, #Year = ##WHERE##<br/>
EXEC Proc_Custom_PRDetails #MonthNumber = ##ORDERBY## #Year = ##WHERE##<br/>
Any help would be appreciated (Thanks in advance Brendan). Lastly, don't get too caught up in the names of specific objects as I tried to change names to protect the innocent.
Those macros for queries are not meant to be used with stor procs. The system generates this false condition 1=1 in case if you don't pass anything so it won't break the sql statement like the one below:
SELECT ##TOPN## ##COLUMNS##
FROM View_CMS_Tree_Joined AS V
INNER JOIN CONTENT_MenuItem AS C
ON V.DocumentForeignKeyValue = C.MenuItemID AND V.ClassName = N'CMS.MenuItem'
WHERE ##WHERE##
ORDER BY ##ORDERBY##
You need to convert you stor proc to SQL statement then you can use these SQL macros or use stor proc without parameters
If look at the query above top and where are not good because system will do adjustment, but you can use order by and columns, but they both must be present (I think it passes them as is):
exec proc_test ##ORDERBY##, ##COLUMNS##
Honestly I would advice against doing this, plus you won't gain much by calling stor proc.

Query referencing another query

I can't execute a query in Power Query and the error that throws me is like:
Formula.Firewall: Query XXX references other queries or steps, so it may not directly access a data source. Please rebuild this data combination.
The code within this query is as below:
let
CallToFunction = myFunction,
#"Invoked Function" = CallToFunction(),
Source = Oracle.Database("myServer", [Query="SELECT * FROM myTable WHERE CustomerPK IN (" & #"Invoked Function" & ")"])
in
Source
myFunction is a function that uses a couple of other queries and eventually returns a string of primary keys that I can use to fill in the parenthesis of the WHERE clause of my SQL statement.
When I invoke the function alone it works correctly, so this must be an issue of how to call the function within the last query.
Any ideas?
You need to set the privacy settings of your data sources & workbook.
See https://support.office.com/en-ca/article/Privacy-levels-Power-Query-cc3ede4d-359e-4b28-bc72-9bee7900b540?ui=en-US&rs=en-CA&ad=CA

ADO on Access Lookup field, getting wrong field returned

I'm in Excel 2010 VBA, using ADO 2.8 to query an Access 2010 database. I don't own the database and don't have any authority to make any changes to it. I've been working with Excel VBA for many years but my Access knowledge is sketchy.
Using the same SQL as one of the queries in the database (copied from the Access query and pasted into Excel VBA), I get different results in some fields than that query in the database gets.
For the affected fields, I see that in Access those fields are defined as lookups. Here's an example lookup from one of the affected fields' Row Source property:
SELECT [Signers].[SignerID], [Signers].[SignerName] FROM Signers ORDER BY [SignerID], [SignerName];
In the Access database, where the SQL statement refers to that field, the query returns SignerName.
But in my ADO code, where the very same SQL statement refers to that field, the query returns SignerID, not SignerName.
Is there something I can do from my ADO code to get SignerName instead of SignerID, from the same SQL statement? Or do I need to modify the SQL statement?
Thanks,
Greg
Update:
On the Access side, I think I see now why only SignerName appears. On the field's Lookup tab, the Column Widths property is:
0";1.2605"
So I guess SignerID is there in the Access query result but with a column width of 0.
Unfortunately that doesn't help me on the ADO side. Any suggestions on getting SignerName instead of SignerID in the ADO query result?
Update2:
Here's a sample SQL statement that returns different fields depending on either it's in Access or in ADO:
SELECT MasterAccount.[SignerKey1]
FROM MasterAccount ;
Per Preet's request, here's the ADO code in Excel VBA:
strDatabasePath = rgDatabasePathCell.Value 'rgDatabasePathCell is a worksheet cell object.
strPWD = DATABASE_PASSWORD
Set cnn = New ADODB.Connection
cnn.Provider = "Microsoft.ACE.OLEDB.12.0"
cnn.ConnectionString = "Data Source='" & strDatabasePath & "';Jet OLEDB:Database Password='" & strPWD & "';"
cnn.Open
Set cmd = New ADODB.Command
cmd.ActiveConnection = cnn
cmd.CommandType = adCmdText
cmd.CommandText = strSQL
Set rst = New ADODB.Recordset
rst.Open cmd.Execute
shMA.Cells(2, 1).CopyFromRecordset rst 'shMA is a worksheet object.
Update 3:
It occurred to me that from what I've said so far, it might seem like I could just change this:
SELECT MasterAccount.[SignerKey1]
FROM MasterAccount ;
to this:
SELECT [Signers].[SignerName]
FROM MasterAccount ;
But there are 13 affected lookup fields, all with exactly the same "Row Source" property text as shown above, and all return different SignerName items for each row. I don't know why they are all returning different items per row; I have not been able to find any difference in the way they are defined. I've been tasked with getting the same result in Excel as that Access query gets.
Update 4:
VBlades -- Thanks, I found the form that has a tab with dropdowns for each of the 13 SignerKey-n fields. If I right-click that form and choose Form Properties, the RecordSource property is:
SELECT MasterAccount.*, Bank.BankRating FROM Bank INNER JOIN MasterAccount ON Bank.BankID = MasterAccount.Bank;
However I don't understand how that would be selecting a different SignerName item for each of the 13 SignerKey-n fields, or what to do with this information to get the same results in ADO as in the Access query. Any suggestions?
Update 5:
I may be close to a workaround. If I do this, I get the SignerName field for SignerKey1:
SELECT Signers.SignerName
FROM Signers RIGHT JOIN MasterAccount ON Signers.SignerID = MasterAccount.SignerKey1.Value;
And if I do this, I get different SignerName items for each field on each row:
SELECT Signers.SignerName, Signers_1.SignerName, Signers_2.SignerName
FROM Signers AS Signers_2 INNER JOIN (Signers AS Signers_1 INNER JOIN (Signers RIGHT JOIN MasterAccount ON Signers.SignerID = MasterAccount.SignerKey1.Value) ON Signers_1.SignerID = MasterAccount.SignerKey2.Value) ON Signers_2.SignerID = MasterAccount.SignerKey3;
That works both in an Access query and in ADO. Next step, I'll try to add these joins to the main SQL statement.
Update 6:
Well, when I try to add even one of those 13 joins to the main SQL statement, it works fine in an Access query, but in ADO I get the error:
Row handles must all be released before new ones can be obtained.
So I'm stuck. Any suggestions?
I've raised the issue with the database owner, but they don't know why the affected fields' Row Source property includes SignerID, so I'm not sure if that's going to help.
You can do the following (simplest way)
Exclude [Signers].[SignerID] from the Query
SELECT [Signers].[SignerName] FROM Signers ORDER BY [SignerID], [SignerName];
Or, create Composite field containing both [SignerID], [SignerName] and extract any part using VBA that you are familiar with:
SELECT ([SignerID] & "_" & [SignerName]) As Composite FROM Signers ORDER BY [SignerID], [SignerName]
Regards,
Okay, I worked around the problem by getting a separate recordset of the SignerID and SignerName fields from the Signers table.
Then I looped through all the rows of each affected field, looked up SignerID in the 2nd table, and swapped in SignerName for SignerID in the original table.
I tried to do that in ADO, but got the error "An UPDATE or DELETE query cannot contain a multi-valued field". So instead I made the swaps after copying the recordset to the Excel worksheet.
I would have liked to know how to handle it all in ADO, but this works. All is well now.

Excel Will not Import a Table From Access

I'm Using Excel/Access 2007. I made an Access query in Access, and I tried to import it into Excel using The Data Tab -> Get External Data Subtab -> From Access. I chose my Database, and chose the Query I wanted to import. However, only the headers of the table as well as 2 blank lines show up (as evidenced by their being formatted as a table). There is definitely data that is returned in the query, that I can verify by checking Access. Any help would be greatly appreciated
As an aside, can this be done programatically?
EDIT: Here is the SQL query in all it's glory
SELECT [Meter#], [LDC#], [ESCO#], [Brand], [LDCName], [RateClass], [RateSubClass], [CustName],
[DemandZone], [Type], dbo_Forecasts.Name AS ForecasForecastType,
Min(IntervalMeterConsumption.[DateFrom]) AS ConsumptionStart, IntermediateLog.[MaxOfDateRead] AS ConsumptionEnd,
Sum([kWh])/(Sum([Interval])/365) AS AverageAnnual
FROM (IntermediateLog
INNER JOIN (
(Premise INNER JOIN Meters ON Premise.PremiseCt = Meters.PremiseCt)
INNER JOIN IntervalMeterConsumption
ON Meters.Meterid = IntervalMeterConsumption.MeterID)
ON IntermediateLog.[LDC#] = Premise.CustomerPremiseNo)
INNER JOIN dbo_Forecasts ON Meters.ForecastID = dbo_Forecasts.ForecastID
WHERE ((([MaxOfDateRead]-[DateFrom])<=380))
GROUP BY IntermediateLog.[Meter#], IntermediateLog.[LDC#], IntermediateLog.[ESCO#],
IntermediateLog.Brand, IntermediateLog.LDCName, IntermediateLog.RateClass,
IntermediateLog.RateSubClass, IntermediateLog.CustName, IntermediateLog.DemandZone,
IntermediateLog.Type, dbo_Forecasts.Name, IntermediateLog.MaxOfDateRead;
You could try removing the where clause just temporarily to see if that makes a difference.
When you run the query in Access does it ask for a parameter?
The code to export a query to Excel from Access is as follows:
DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel12, "Query/Table Name", "c:\export.xls"
thanks Mark

Resources