Excel getting current directory in Power Query - excel

I have been trying to get current directory into Power Query. But it somehow doesn't work. How can I get current directory, to make the path dynamic for my Query, so that in case the file moved a new directory, I will have no issue with retrieving data into Power Query. Here is the code I tried with:
let
Source = Excel.CurrentWorkbook(){[Name="pathTable"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Path", type text}}),
Path = Table.ReplaceValue(#"Changed Type","\[PathForSummaryFiles.xlsx]Path","\summary.xlsx",Replacer.ReplaceText,{"Path"})
GetFilesFromFolder = Folder.Files(Path)
in
GetFilesFromFolder
the code above throws an error.

Is this what you are trying to do?
In excel, name a cell DirectoryRangeName using formulas ... name manager
Within that cell, put in a formula to capture the path of that file
=LEFT(CELL("filename",A1),FIND("[",CELL("filename",A1))-1)
or enter your own path such as:
c:\directory\subdirectory\
Then, once in powerquery, read that value, and combine however you want to reference it such as
let Directory = Excel.CurrentWorkbook(){[Name="DirectoryRangeName"]}[Content]{0}[Column1],
Source = Excel.Workbook(File.Contents(Directory & "abs.xlsx"), null, true)
in Source
Or
let Directory = Excel.CurrentWorkbook(){[Name="DirectoryRangeName"]}[Content]{0}[Column1],
GetFilesFromFolder = Folder.Files(Directory)
in GetFilesFromFolder
Instead of a formula in the range name, you could simply put a full filepath such as c:\temp\a.xlsx
and then read it within powerquery
let FilePath= Excel.CurrentWorkbook(){[Name="DirectoryRangeName"]}[Content]{0}[Column1],
Source = Excel.Workbook(File.Contents(FilePath), null, true)
in Source

Related

Power Query: easy way to select the file the query is applied to?

In our lab we have a system that many people uses and produces a oddly shaped txt file with the results. I created a power query that cleans the file and I would like to share this with others (not very computer savvy) so they can apply it to the files they will generate.
What can I do to make it as easy as possible for other users to select the file they want the query to be applied to? Example: is there an easy way to create button that opens a dialog requesting the file location? Right now I have to edit the query source to select the data, this approach is clunky and will be confusing for some of my colleagues.
let
Source = Table.FromColumns({Lines.FromBinary(File.Contents("X:\foo\foo.txt"), null, null, 1252)}),
#"Removed Top Rows2" = Table.Skip(Source,32),
#"Removed Bottom Rows" = Table.RemoveLastN(#"Removed Top Rows2",16),
#"Other Steps" = ...
Thanks!
You can directly grab a filepath from a range name cell without a function by
let
NameValue= Excel.CurrentWorkbook(){[Name="rangenamehere"]}[Content]{0}[Column1],
Source = Table.FromColumns({Lines.FromBinary(File.Contents(NameValue), null, null, 1252)}),
Or if you wanted the VBA route for file prompt
1 Create a range name, here aaa
2 Use VBA to populate it using a file prompt
Sub prompt()
Dim FName As Variant
FName = Application.GetSaveAsFilename("", "Data file (*.xl*),*.xl*", 1)
If FName = False Then
MsgBox "False"
Exit Sub
End If
Range("aaa").Value = FName
End Sub
3 Refer to the named range in powerquery you set up
let
NameValue= Excel.CurrentWorkbook(){[Name="aaa"]}[Content]{0}[Column1],
Source = Table.FromColumns({Lines.FromBinary(File.Contents(NameValue), null, null, 1252)}),
4 Tack on code at end of VBA to refresh all queries or specific query
ActiveWorkbook.RefreshAll
or
ActiveWorkbook.Queries("QueryNameHere").Refresh
I found this post from 2014 that works pretty well. You write a function on Query (fnGetParameter) that reads the file location from a table and then you feed it to the query that processes the data.
All the user needs to do is write the file location on the table and name and refresh.
I changed the first to lines on my PowerQuery code to look like this:
Fileloc = fnGetParameter("File Path"),
Source = Table.FromColumns({Lines.FromBinary(File.Contents(Fileloc), null, null, 1252)}),
Any suggestions to make it even better?
You can make the fnGetParameter into a one-liner:
= ( getValue as text ) => Excel.CurrentWorkbook(){[Name=”Parameters”]}[Content]{[Parameter=getValue]}?[Value]?

Microsoft excel Power Query (windows) to VBA (Mac)

I have created a query which takes data from a folder, and orders the data in such a way that I need..
The problem is that it won't work on MacOs.. The get from folder function does not exist in MacOs, I understood that I need to use VBA in order to do the same thing on MacOs..
I have no clue on how to use VBA
These are some of the steps in my power query:
= Folder.Files("C:\Users\location..")
= Table.SelectRows(Source, each [Attributes]?[Hidden]? <> true)
= Table.AddColumn(#"Filtered Hidden Files1", "Transform File", each #"Transform File"([Content]))
And so on..
How could I mimic these in MacOs with VBA?
So here is a proposed solution, but unfortunately it runs into permission problems, which maybe someone else can help with.
First have three cells in your spreadsheet. Use the Excel name manager to name them OS, FilePath and FileName respectively. Their content is:
OS: =LET(vers,INFO("OSVERSION"),IFERROR(LEFT(vers,FIND(" ",vers)-1),vers))
FilePath: =IF(A1="Windows","C:\...\","/Users/.../")
FileName= report.csv
(obviously subsititute the actual windows & mac filepaths above)
As the start of your Power Query M code, use:
let
FilePath= Excel.CurrentWorkbook(){[Name="FilePath"]}[Content]{0}[Column1],
FileName= Excel.CurrentWorkbook(){[Name="FileName"]}[Content]{0}[Column1],
Source = Csv.Document(File.Contents(FilePath & FileName), [Delimiter = ",", Columns = 12, Encoding = 65001, QuoteStyle = QuoteStyle.None])
in
Source
This works fine on the Windows side - I am having some problems on Mac, getting an error such as:
Query 'FetchReport (2)' (step 'AutoRemovedColumns1') is accessing data sources that have privacy levels which cannot be used together. Please rebuild this data combination.0:

Relative folder/file path in PowerQuery (M)

Given: 2 excel files (A and B) that are located in the same folder.
Task: set Source for a given PQ in Workbook B to reference Workbook A in a "relative" manner - when both files are moved to another PC the reference isn't broken.
Is there anything in M-language to get current folder or file path?
You need to give a name 'Path' to some cell where current path is defined
=LEFT(CELL("filename");SEARCH("[";CELL("filename");1)-1)
Then use following in the query:
Path = Excel.CurrentWorkbook(){[Name="Path"]}[Content]{0}[Column1],
FullPath = Path & "file.xlsx",
Source = Excel.Workbook(File.Contents(FullPath), null, true)
One big disadvantage of the approach - is that you need to Calculate your workbook after localtion is changed or set Calculation mode to Automatic.
If someone know how can we do not use cell for getting current path - it will solve a problem with modifying file and Calculation mode.
Give an excel cell a range name, like LocVariable, and put some text or excel formula in that cell to evaluate to the filepath you want, such as c:\temp
Then in powerquery, in home ... advanced editor ... edit your Source statement to use that path
let Loc = Text.From(Excel.CurrentWorkbook(){[Name="LocVariable"]}[Content]{0}[Column1]),
Source = Excel.Workbook(File.Contents(Loc&"\data.xlsx"), null, true),
or in one step
let Source = Excel.Workbook(File.Contents(Text.From(Excel.CurrentWorkbook(){[Name="LocVariable"]}[Content]{0}[Column1])&"\data.xlsx"), null, true),

Power Query File Count function

I am trying to come up with a small function that will update my main query. There is one line in my code that is currently static, and I would like it to update as I add files to my folder. The number is based off the files in the folder, 1 - "Files in the Folder". Currently there are 14 files in my folder, so the line looks like so:
= Table.RenameColumns(#"Added LAST_FIRST_MID NAME",{{"1", "Report Count"}, {"-13", "Index"}})
So, the bold number needs to be a function of 1 - Count(Files in Folder). The problem lies in the fact that I have no idea how to create a function from scratch. I tried creating a file with the following code and creating a function from that table.
let
Source = Folder.Files("P:\CREDIT DEPT\Credit Bureau - Analysis\BOSP CC DataFiles"),
#"Added Index" = Table.AddIndexColumn(Source, "Index", 0, -1)
in
#"Added Index"
This is my first attempt at trying to create a function, I think that I'm on the right path, but I'm not sure where to go from here. Thanks in advance for your help.
If you are trying to count number of files and then use that variable, try below
Use Home...Advanced Editor... to paste in the first row above where you intend to reference the result
FileCount = Text.From(1 - Table.RowCount(Folder.Files("P:\CREDIT DEPT\Credit Bureau - Analysis\BOSP CC DataFiles"))),
#"Rename" = Table.RenameColumns(#"Added LAST_FIRST_MID NAME",{{"1", "Report Count"}, {FileCount, "Index"}})

Get Current Workbook Path - Excel Power Query

Trying to add a custom column and populating the value with the current workbook path name.
I have tried Excel.Workbook.name and Excel.CurrentWorkbook() and other objects, but it seems those are limited to pulling data.
in VBA this is simply WorkbookObject Path property. but with power query its another story. The references and libraries on Microsoft site are limited for power query.
https://msdn.microsoft.com/en-us/library/mt779182.aspx
Instead of using VBA, you can use the following method which merely involves using an Excel formula:
Define the following formula in Excel and name this cell "FilePath":
=LEFT(CELL("filename",$A$1),FIND("[",CELL("filename",$A$1),1)-1)
Add the following function in PowerQuery. This will return the current directory:
() =>
let
CurrentDir = Excel.CurrentWorkbook(){[Name="FilePath"]}[Content]{0}[Column1]
in
CurrentDir
Now you can import your CSV (or other) file from the current directory:
let
Source = Csv.Document(File.Contents(currentdir() & "filename.csv"),[Delimiter=";", Columns=15, Encoding=65001, QuoteStyle=QuoteStyle.None])
in
Source
Credits: https://techcommunity.microsoft.com/t5/excel/power-query-source-from-relative-paths/m-p/206150
There is no direct way to do this in Power Query. If you can fill the value into a cell you can get that value through Excel.CurrentWorkbook.
You can use VBA and have a cell filled in when the file is opened during the Workbook_Open event:
Private Sub Workbook_Open()
Dim root As String
root = ActiveWorkbook.path
Range("root").Value = root
'root is the named range used in power query.
End Sub
You can then get this variable from the named range ("root") into Power Query by doing something along these lines:
let
Source = Excel.CurrentWorkbook(){[Name="root"]}[Content][Column1]{0}
in
Source

Resources