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),
Related
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
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:
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
I have some data in an excel file.
At first, I read the file and create a list of names stored in a cell through this command:
[status,sheets] = xlsfinfo(filename);
and I get:
sheets = {'A1','A2','B1','B2','C1'};
(these are the names of excelsheets in the excel file)
and through some process I obtain a matrix for each of these names (excelsheets). The final matrix for each is called:
completeData = [x,v,z,y,s];
Now, I want to:
change the name of "completeData" variable to each of its corresponding excelsheet (from the "sheets" cell).
then save this newly renamed variable (the old "completeData") with the name of its corresponding excelsheet (again from the "sheets" cell).
So far, I have only managed to save each completeData matrix resulting for each excel sheet separately with the name of the sheets [which is point number 2] through this command:
save(sprintf('%s',sheets{excelSheet}),'completeData');
(here I have a loop over "excelsheet")
The problem is that when I have mange excel sheets, and save all of them in a folder my hard disk, whenever I run any of these saved variables I get "completeData" in the workspace which is not what I want. I want to get also the name of the excelsheet.
How can I do this?
P.S. through this command:
eval(sprintf([sheets{excelsheet} '=completeData;']));
(again another loop over excelsheet)
I have managed to create several matrices with the names of excel sheets. But I do not know how I can save these very good newly created variables through a loop so that I do not do it one by one.
Following up the comments above, I tried to write you a simplified example:
%% Initialise
names = {'name1', 'name2', 'name3'};
data = randn(10, 3);
%% it create three fields called name1, name2 and name3 from data, in s
for ind=1:size(data, 2)
s.(names{ind}) = data(:, ind);
end
Hope it helps!
So this is how it worked:
First read information:
[status,sheets] = xlsfinfo(filename);
NamesList = sheets(:,1);
Now, apply the primarily collected information to read again with details:
for ind = 1:length(NamesList)
% Only read those particular sheets
[num,txt,raw] = xlsread(filename,NamesList{ind,:});
var.(NamesList{ind})={txt(:,MyColumn),num};
clear num txt raw
end
I want to write a program that is able to read a specific range of numerous excel files in a folder.
because I need MATLAB to read from several excel files, I can't use a coding like this :
xlsread('Report1',1,'k41')
Is it possible to modify below codes in a way to be able to read 'K41' cellular from each excel file?
clc
clear all
Folder = 'D:\Program Files\MATLAB\R2013a\bin';
XLfiles = dir(fullfile(Folder, '*.xlsx'));
for i = 1:length(XLfiles)
data = xlsread(fullfile(Folder, XLfiles(i).name));
end
As excaza said, xlsread should work, just check the 'range' parameter from xlsread, needs to be a string in this format (this is to import only C1).
'C1:C2'
If you use K41:K41 it imports nothing, as it is a 0 range. Maybe that is the confusion here.
See if this might work
all_cells = []; %store all your cells in here
Folder = 'D:\Program Files\MATLAB\R2013a\bin';
XLfiles = dir(fullfile(Folder, '*.xlsx'));
for i = 1:length(XLfiles)
all_cells (end+1)= xlsread(fullfile(Folder, XLfiles(i).name), 'K41:K42');
end