is there a command of Matlab to get the number of the written cols in excel file?
this is my excel file:
this is my code:
e = actxserver ('Excel.Application'); %# open Activex server
filename = fullfile(pwd,'example2.xlsx'); %# full path required
ewb = e.Workbooks.Open(filename); %# open the file
esh = ewb.ActiveSheet;
And I tried:
intCol = Range('IV1').End(xlLeft).Col;
thank you :]
What about:
[num, txt, raw] = xlsread('example2.xlsx');
intCol = size(raw, 2);
Related
If i have an Excel "Covid19_report &todaysdate. &time..xlsx" file in a folder called F:\A
and I want to put this exact file into folder F:\B but duplicated 6 times like this:
"1_Covid19_report &todaysdate. &time..xlsx"
"2_Covid19_report &todaysdate. &time..xlsx"
"3_Covid19_report &todaysdate. &time..xlsx"
"4_Covid19_report &todaysdate. &time..xlsx"
"5_Covid19_report &todaysdate. &time..xlsx"
"6_Covid19_report &todaysdate. &time..xlsx"
is there a macro to do that?
The SAS function FCOPY will be helpful.
Copying binary files requires a fileref be created with options such as RECFM=N and LRECL=<filesize>
Example:
Create a sample Excel file and copy it 6 times to target files having an index prefix in their filenames.
* Create sample Excel file for copying;
ods noresults;
ods excel file='c:\temp\prices.xlsx';
proc print data=sashelp.stocks;
run;
ods excel close;
ods results;
* Copy a source file 6 times to a target file with an index number prefix name pattern;
data _null_;
length source_ref target_ref $8;
* determine name part from full pathname;
source_file = 'c:\temp\prices.xlsx';
source_name = scan(source_file,-1,'\');
* determine source file size for efficient options;
* NOTE: FCOPY only works on files < 1G in size;
rc = filename(source_ref, source_file);
fid = fopen(source_ref);
bytes = finfo(fid,'File size (bytes)');
fid = fclose(fid);
rc = filename(source_ref);
options = 'recfm=n lrecl='||trim(bytes);
* prepare SOURCE fileref;
source_ref = '';
rc = filename(source_ref, source_file, 'DISK', options);
* duplicate in same folder (via transtrn);
do index = 1 to 6;
* compute target file name and corresponding full path;
target_name = cats(index,"_",source_name);
target_file = transtrn(source_file, trim(source_name), target_name);
* create temporary TARGETR fileref (due to ref value passed in being blank);
target_ref = '';
if 0 = filename (target_ref, target_file, 'DISK', options) then do;
rc = fcopy ('source', target_ref);
rc = filename(target_ref); * clear TARGET fileref;
end;
end;
stop;
run;
i tried doing this, but do not work:
%let todaysDate = %sysfunc(today(), yymmdd10.); %put &todaysDate;
data _null_; ftime = intnx('hour',time(),0,'b'); cftime =
compress(put(ftime,hhmm.),":"); call symputx("ftime",cftime); run;
%put &=ftime.;
%let path = F:\A;
%let file = COVID-19 Report &todaysdate. &ftime.;
filename source "&path.\&file.";
data _null_; length target_ref $8;
do index = 1 to 6;
target_file = cats("&path.",index,"_&file.");
target_ref = '';
* create temporary fileref (due to initial ref value being blank);
if 0 = filename (target_ref, target_file) then do;
rc = fcopy ('source', target_ref);
rc = filename(target_ref);
end; end; stop; run;
I'm in need of optimizing import of .xls files to matlab due to xlsread being very time consuming with large amount of files. Current xlsread script as follows:
scriptName = mfilename('fullpath');
[currentpath, filename, fileextension]= fileparts(scriptName);
xlsnames = dir(fullfile(currentpath,'*.xls'));
xlscount = length(xlsnames);
xlsimportdata = zeros(7,6,xlscount);
for k = 1:xlscount
xlsimport = xlsread(xlsnames(k).name,'D31:I37');
xlsimportdata(:,1:size(xlsimport,2),k) = xlsimport;
end
I have close to 10k files per week that needs processing and with approx. 2sec per file processed on my current workstation, it comes in at about 5½ hours.
I have read that ActiveX can be used for this purpose however that is far beyond my current programming skills and have not been able to find a solution elsewhere. Any help on how to make this would be appreciated.
If it is simple to perform with ActiveX (or other proposed method), I would also be interested in data on cells D5 and G3, which I am currently grabbing from 'xlsnames(k,1).name' and 'xlsnames(k,1).date'
EDIT: updated to reflect the solution
% Get path to .m script
scriptName = mfilename('fullpath');
[currentpath, filename, fileextension]= fileparts(scriptName);
% Generate list of .xls file data
xlsnames = dir(fullfile(currentpath,'*.xls'));
xlscount = length(xlsnames);
SampleInfo = cell(xlscount,2);
xlsimportdata = cell(7,6,xlscount);
% Define xls data ranges to import
SampleID = 'G3';
SampleRuntime = 'D5';
data_range = 'D31:I37';
% Initiate progression bar
h = waitbar(0,'Initiating import...');
% Start actxserver
exl = actxserver('excel.application');
exlWkbk = exl.Workbooks;
for k = 1:xlscount
% Restart actxserver every 100 loops due limited system memory
if mod (k,100) == 0
exl.Quit
exl = actxserver('excel.application');
exlWkbk = exl.Workbooks;
end
exlFile = exlWkbk.Open([dname filesep xlsnames(k).name]);
exlSheet1 = exlFile.Sheets.Item('Page 0');
rngObj1 = exlSheet1.Range(SampleID);
xlsimport_ID = rngObj1.Value;
rngObj2 = exlSheet1.Range(SampleRuntime);
xlsimport_Runtime = rngObj2.Value;
rngObj3 = exlSheet1.Range(data_range);
xlsimport_data = rngObj3.Value;
SampleInfo(k,1) = {xlsimport_ID};
SampleInfo(k,2) = {xlsimport_Runtime};
xlsimportdata(:,:,k) = xlsimport_data;
% Progression bar updater
progress = round((k / xlscount) * 100);
importtext = sprintf('Importing %d of %d', k, xlscount);
waitbar(progress/100,h,sprintf(importtext));
disp(['Import progress: ' num2str(k) '/' num2str(xlscount)]);
end
%close actxserver
exl.Quit
% Close progression bar
close(h)
Give this a try. I am not an ActiveX Excel guru by any means. However, this works for me for my small amount of test XLS files (3). I never close the exlWkbk so I don't know if memory usage is building or if it automatically cleaned up when descoped after the next is opened in its place ... so use at your own risk. I am seeing an almost 2.5x speed increase which seems promising.
>> timeit(#getSomeXLS)
ans =
1.8641
>> timeit(#getSomeXLS_old)
ans =
4.6192
Please leave some feedback if this work on large number of Excel sheets because I am curious how it goes.
function xlsimportdata = getSomeXLS()
scriptName = mfilename('fullpath');
[currentpath, filename, fileextension]= fileparts(scriptName);
xlsnames = dir(fullfile(currentpath,'*.xls'));
xlscount = length(xlsnames);
xlsimportdata = zeros(7,6,xlscount);
exl = actxserver('excel.application');
exlWkbk = exl.Workbooks;
dat_range = 'D31:I37';
for k = 1:xlscount
exlFile = exlWkbk.Open([currentpath filesep xlsnames(k).name]);
exlSheet1 = exlFile.Sheets.Item('Sheet1'); %Whatever your sheet is called.
rngObj = exlSheet1.Range(dat_range);
xlsimport = cell2mat(rngObj.Value);
xlsimportdata(:,:,k) = xlsimport;
end
exl.Quit
I need to write an excel file to many folders ( folder* ) under D:\ and loop over them to further process individually.
i tried the following code for long time ..
srcFolders = dir('D:\folder*');
for i = 1 : length(srcFiles)
filename = strcat(path,'\',srcFiles(i).name);
xlswrite('srcFolders\filename.xls', srcFolders(folder).name,'Sheet1', folder_range);
end
I'm assuming that you want to write different sets of data to a Excel file and were just having some trouble. If that's not accurate comment and let me know.
%Just generating some arbitrary data
data = arrayfun(#(m,n) rand(m,n), randi(50, 9, 1), randi(50, 9, 1), 'uni', 0);
%The base file path
path = 'D:';
%The pattern used to choose the folders
folderPattern = 'folder*';
%The files you want to write to
srcFiles = {'A', 'B', 'D'};
%And the extension
ext = '.xlsx';
%Get the path of the folders
srcFolders = dir(fullfile(path, folderPattern));
srcFolders = fullfile(path, {srcFolders.name});
%Construct the full file path
fullPath = cellfun(#(f) fullfile(f, strcat(srcFiles(:), ext)), srcFolders, 'uni', 0);
fullPath = vertcat(fullPath{:});
%Write the data to the files
for i = 1:length(fullPath)
xlswrite(fullPath{i}, data{i})
end
Edit:
Based on OP's feed.
Note for the second overhaul. I didn't test this and I'm done. This was way to much for a single question and you are abusing the way this website is supposed to work.
%The base file path
path = 'D:';
%Relative reference to reference images
ImageRefLocations = {'Ref\RefI1.jpg', 'Ref\RefI2.png', 'Ref\RefI3.jpg'};
%Base Image location
baseImage = fullfile(path, ImageRefLocations(:));
%The pattern used to choose the folders
folderPattern = 'folder*';
%The image extension
[~, ~, ext] = unique(cellfun(#(f) fileparts(f), baseImage, 'uni', 0));
%The excel extension
ExcelExt = '.xlsx';
msg = {' = no'; ' = ok'};
i0 = cellfun(#(f) imread(f), baseImage, 'uni', 0);
%Get the path of the folders
srcFolders = dir(fullfile(path, folderPattern));
isDir = [srcFolders.isdir];
srcFolders = {srcFolders(isDir).name}';
PathedFolders = fullfile(path, srcFolders);
excelFiles = fullfile(path, strcat(srcFolders, ExcelExt));
for i = 1:length(PathedFolders)
f = PathedFolders{i};
Images = cellfun(#(x) dir(fullfile(f, ['*', x])), ext, 'uni', 0);
Images = vertcat(Images{:});
if isempty(Images)
continue
end
Images = {Images.name}';
[~, ImageNames, ~] = cellfun(#(x) fileparts(x), Images, 'uni', 0);
ImageList = fullfile(f, Images);
match = zeros(size(ImageList));
for j = 1:length(ImageList)
image = imread(ImageList{j});
for k = 1:length(i0)
if ~all(size(image) == size(i0{k}))
continue
end
match(j) = all(image(:) == i0{k}(:));
if match(j)
continue
end
end
end
matchMessage = strcat(Images, msg(match + 1));
xlswrite(excelFiles{i}, matchMessage)
end
I have a code in matlab. After I have run my program, a file 'example2.xlsx' was created.
Now I have the code below and I want matlab to replace the current 'example2.xlsx' by the new 'example2.xlsx' (saving automatically without asking me if I want to replace it):
e = actxserver ('Excel.Application'); % # open Activex server
filename = fullfile(pwd,'example2.xlsx'); % # full path required
ewb = e.Workbooks.Open(filename); % # open the file
esh = ewb.ActiveSheet;
str = num2str(num_rows+1);
esh.Range(strcat('J',str)).Interior.Color = clr;
sheet1 = e.Worksheets.get('Item', 'Sheet1');
range1 = get(sheet1,'Range', strcat('A',str),strcat('I',str));
range1.Value = values{num_rows+1};
[num, txt, raw] = xlsread('example2.xlsx');
num_rows = length(num(:,1));
xlWorkbookDefault = 51; % # it's the Excel constant, not sure how to pass it other way
ewb.SaveAs(fullfile(pwd,'example2'), xlWorkbookDefault)
ewb.Close(false)
e.Quit
e.delete
You can set the DisplayAlerts property of the Excel application object to false to stop these dialogs from appearing.
The following is a simplified version of your code:
e = actxserver ('Excel.Application'); % # open Activex server
filename = fullfile(pwd,'example2.xlsx'); % # full path required
ewb = e.Workbooks.Open(filename); % # open the file
esh = ewb.ActiveSheet;
sheet1 = e.Worksheets.get('Item', 'Sheet1');
range1 = get(sheet1,'Range', 'A1');
range1.Value = 3;
set(e, 'DisplayAlerts', 0); % # Stop dialog!
xlWorkbookDefault = 51; % # it's the Excel constant, not sure how to pass it other way
ewb.SaveAs(fullfile(pwd,'example2'), xlWorkbookDefault)
ewb.Close(false)
e.Quit
e.delete
this code has to color the J1 cell by a given rgb.
row_number_excel = 1;
representative_red = 205;
representative_green = 211;
representative_blue = 201;
headers = {'J'};
rgb = [representative_red representative_green representative_blue]; %# if you have 0 to 1 values multiply by 255 and round
clr = rgb * [1 256 256^2]'; %# convert to long number Excel understands
pwd = 'D:\grapes\main';
e = actxserver ('Excel.Application'); % open Activex server
filename = fullfile(pwd,'example.xls'); %# full path required
if exist(filename,'file')
ewb = e.Workbooks.Open(filename); %# open the file
else
error('File does not exist.') %# or create a new file
end
esh = ewb.ActiveSheet;
for c = 1:row_number_excel
str = num2str(row_number_excel);
esh.Range(strcat(headers{1},str)).Interior.Color = clr;
end
ewb.Save
ewb.Close(false)
e.Quit
I tried to run this code, but the cell was colored by a different color than the given rgb. When I ran the code in the second time, a file was created in my directory, named: "2E60F720". its type is 'file'. Then the program ran and ran and wasn't stopped till I stopped 'EXCEL.EXE' by the task manager. After that the matlab wrote me this:
"??? Error: The remote procedure call failed.
Error in ==> test1 at 212 ewb.
Close(false);"
can someone help me please?
I captured the screen. in the left side, the program is still running, in the right side, this is my directory. I marked the file that was created.
thanks!
the solution that solved my question is:
row_number_excel = 1;
representative_red = 205;
representative_green = 211;
representative_blue = 201;
headers = {'J'};
rgb = [representative_red representative_green representative_blue]; %# if you have 0 to 1 values multiply by 255 and round
clr = rgb * [1 256 256^2]'; %# convert to long number Excel understands
pwd = 'D:\grapes\main';
e = actxserver ('Excel.Application'); % open Activex server
filename = fullfile(pwd,'example.xls'); %# full path required
if exist(filename,'file')
ewb = e.Workbooks.Open(filename); %# open the file
else
error('File does not exist.') %# or create a new file
end
esh = ewb.ActiveSheet;
for c = 1:row_number_excel
str = num2str(row_number_excel);
esh.Range(strcat(headers{1},str)).Interior.Color = clr;
end
xlWorkbookDefault = 51; %# it's the Excel constant, not sure how to pass it other way
ewb.SaveAs(fullfile(pwd,'example2'), xlWorkbookDefault)
ewb.Close(false)
e.Quit
thanks to #yuk!
The trouble line is saving the file with ewb.Save.
Your file is actually in the old format (excel 2003), not sure if it's support true RGB colors, it might be the reason.
I'd recommend to save the file with a new name and the latest format. Put this as the last lines:
xlWorkbookDefault = 51; %# it's the Excel constant, not sure how to pass it other way
ewb.SaveAs(fullfile(pwd,'example2'), xlWorkbookDefault)
ewb.Close(false)
e.Quit