I have a 6x7 matrix(A) and some operation I'm doing on it for k=1:50 (number of loops).
I know that in order to write a single matrix in an excel file I need:
xlswrite('Filename.xls', A, 'A1')
How is it possible to write the information after each loop, in that way that each loop starts at position A1+((k-1)*6+1) in Excel and I have all results of Matrix(A) listed one after each other.
Thank you!
When using the XLSWRITE function, you can avoid having to compute Excel cell ranges each time, by specifying both sheet number and range, where range only gives the first cell to start at.
It is especially useful if the matrix changes size each iteration; we simply take the last cell used and shift it by the number of rows of the matrix.
Example:
offset = 1;
for i=1:5
%# generate different size matrices each loop
A = ones(randi(4),randi(4)).*i;
%# insert matrix in Excel inside the 1st sheet, starting at cell specifed
xlswrite('filename.xls', A, 1, sprintf('A%d',offset));
%# increment offset
offset = offset + size(A,1);
end
this creates an Excel file with the following content:
1 1
1 1
1 1
2 2 2 2
3 3
3 3
4
4
4
4
5 5 5
5 5 5
5 5 5
5 5 5
Note that a connection is made to Excel then closed each time XLSWRITE is called. This has a significant overhead.
A better approach would be to open Excel once, and reuse the same session to write all of your data, then close it once we are done. However, you will have to call the Office Interop functions yourself.
Since the trick I mentioned above won't work now, I will be using the "Calculate Excel Range" function to compute the cell ranges (there are many other implementations of FEX).
Here is the code (reusing some code from a previous answer):
%# output file name
fName = fullfile(pwd, 'file.xls');
%# create Excel COM Server
Excel = actxserver('Excel.Application');
Excel.Visible = true;
%# delete existing file
if exist(fName, 'file'), delete(fName); end
%# create new XLS file
wb = Excel.Workbooks.Add();
wb.Sheets.Item(1).Activate();
%# iterations
offset = 0;
for i=1:50
%# generate different size matrices each loop
A = ones(randi(4),randi(4)).*i;
%# calculate cell range to fit matrix (placed below previous one)
cellRange = xlcalcrange('A1', offset,0, size(A,1),size(A,2));
offset = offset + size(A,1);
%# insert matrix in sheet
Excel.Range(cellRange).Select();
Excel.Selection.Value = num2cell(A);
end
%# save XLS file
wb.SaveAs(fName,1);
wb.Close(false);
%# close Excel
Excel.Quit();
Excel.delete();
In fact, I ran both version with 50 iterations, and compared timings with TIC/TOC:
Elapsed time is 68.965848 seconds. %# calling XLSWRITE
Elapsed time is 2.221729 seconds. %# calling Excel COM directly
I think that xlswrite will overwrite an existing file, so you're better off gathering all the data, then writing it in one go. Also, writing it all in one go will be faster since it involves opening and closing Excel only once.
However, if you really want to write it in a loop, the following should work (assuming you mean going down):
range = sprintf('A%i:G%i', (k-1)*6+[1 6]);
xlswrite('Filename.xls', A, range);
Note that this won't adjust automatically if A changes size.
Related
I know how to read in multiple Excel files, but am struggling to conduct the same analysis on all of those files. The analysis requires I average some values in different columns, then print those average values to a separate Excel sheet. I can do this with one Excel file, but have trouble figuring out how to print each average value in a different row in the output Excel file. Here is the code I have that works for one file (reads it, averages values in column 4, then prints to a separate Excel file):
data = xlsread('test_1.xlsx');
average_values_1 = data(:,4);
a = [average_values_1];
data_cells = num2cell(a);
column_header ={'Average Value 1'};
row_header(1,1) ={'File 1'}
output = [{' '} column_header; row_header data_cells];
xlswrite('Test Averages.xls', output);
How might I do this over and over again while printing values from each file in the output file as its own table? I suspect a nested loop is in my future.
Thanks in advance.
Here is working example of what you possibly want to do with xlswrite[1]:
filename = 'testdata.xlsx'; % Filename to save average values in
for k = 1:10 % Looping for 10 iterations
sheet = 2; % Selecting sheet2
Avg = randi([1 10],1,1); % Generating a random average each time the loop is run
xlRange = char(64+k); % 65 is the ASCII value of A
xlswrite(filename,Avg,sheet,xlRange); % Writing the excel file
end
This code gives the following output [2] :
Fig.1: Values are saved in a single row of excel file
If you want to get the output in a single column then use this xlRange = ['A',num2str(k)]; instead. It'll give you the following output [2] :
Fig.2: Values are saved in a single column of excel file
[1]: Read the documentation of xlswrite for more details.
[2]: Output values may vary since random integers are generated.
I have a Matlab script with an output of a multidimensional array LCOE (3 dimensions) of size 16:12:34. This output needs to be written to Excel, therefore I use xlswrite.
I have tried this:
T = LCOE(:,:,1);
xlswrite('filename', T, 'sheetname', 'B2');
This does what it's supposed to, but only writes one table to excel, and I would like to write all 34 tables to excel underneath each other, spaced by `2 blank rows.
Then, I tried this:
for y = 1:34
T = LCOE(:,:,y)
xlswrite('filename', T, 'sheetname', strcat('B', num2str(2+(y-1)*18)));
This works, but is very slow, since matlab writes each table separately to excel. Is there a faster way to do this?
Instead of using xlswrite again and again. Dump all the values of a 3D matrix into a 2D matrix and add rows of NaNs so that when you write that to excel file, you get 2 blank rows.
Following code improves the execution time by the factor of more than 10.
LCOE = 100*rand(16,12,34); % Taking random values for LCOE
T = NaN(18*34-2 ,12); % 1. Pre-allocation 2. 16+2 = 18
% Following loop dumps all the values of 3D matrix into a 2-D followed by 2 rows of NaN
% to leave 2 blank rows in excel file.
for k = 1:34
T(18*(k-1)+[1:16], :) = LCOE(:,:,k);
end
xlswrite('filename', T, 'sheetname', 'B2'); % Writing the Excel file
In my system, my code takes about 1 second to execute while your code takes about 10.5 seconds. So that's a significant difference.
I have a looping data matrix in matlab, and I want to write it into same excel file. If I use the xlswrite('name.xls', M) it'll make a 'name.xls' excel, contained one matrix (value of the last looping). How can I write all my looping matrix (lets say it has 10 matrix with 13 columns) in one file excel and that excel file will contain all my matrix with 13 columns (so there'll be 10 rows with 13 columns). Please help, Thanks. -Machmum
In each loop iteration add your newest vector to a single matrix. Then only after the loop, write this matrix to a .xls file:
M = zeros(10,13); %// Pre-allocation like this is essential for speed
for k = 1:10
... %Your code
M(k,:) = ... %//Put your new 1-by-13 vector that you create each iteration here
end
xlswrite(file_name, M)
Although it would be better to create the matrix first and then write it in one go as Dan has suggested, it is possible to specify where xlswrite starts writing, which allows you to append data to existing files. If only specifying a start location, you must also give xlswrite a sheet name. This will be slower than pre-calculating the matrix and then just calling xlswrite once, though.
Simple example:
M = 1:10;
for n = 1:10
t = sprintf('A%d',n); % starting cell A1 through A10
xlswrite('testdata.xls',M*n,'Sheet1',t); % writes one row
end
I have the following code to read off time series data (contained in sheets 5 to 19 in an excel workbook). Each worksheet is titled "TS" followed by the number of the time series. The process works fine apart from one thing- when I study the returns I find that all the time series are shifted along by 5. i.e. TS 6 becomes the 11th column in the "returns" data and TS 19 becomes the 5th column, TS 15 becomes the 1st column etc. I need them to be in the same order that they are read- such that TS 1 is in the 1st column, TS 2 in the 2nd etc.
This is a problem because I read off the titles of the worksheets ("AssetList") which maintain their actual order throughout subsequent codes. Therefore when I recombine the titles and the returns I find that they do not match. This complicates further manipulation when, for example column 4 is titled "TS 4" but actually contains the data of TS 18.
Is there something in this code that I have wrong?
XL='TimeSeries.xlsx';
formatIn = 'dd/mm/yyyy';
formatOut = 'mmm-dd-yyyy';
Bounds=3;
[Bounds,~] = xlsread(XL,Bounds);
% Determine the number of worksheets in the xls-file:
FirstSheet=5;
[~,AssetList] = xlsfinfo(XL);
lngth=size(AssetList,2);
AssetList(:,1:FirstSheet-1)=[];
% Loop through the number of sheets and RETRIEVE VALUES
merge_count = 1;
for I=FirstSheet:lngth
[FundValues, ~, FundSheet] = xlsread(XL,I);
% EXTRACT DATES AND DATA AND COMBINE
% (TO REMOVE UNNECCESSARY TEXT IN ROWS 1 TO 4)
Fund_dates_data = FundSheet(4:end,1:2);
FundDates = cellstr(datestr(datevec(Fund_dates_data(:,1),...
formatIn),formatOut));
FundData = cell2mat(Fund_dates_data(:,2));
% CREATE TIME SERIES FOR EACH FUND
Fundts{I}=fints(FundDates,FundData,['Fund',num2str(I)]);
if merge_count == 2
Port = merge(Fundts{I-1},Fundts{I},'DateSetMethod','Intersection');
end
if merge_count > 2
Port = merge(Port,Fundts{I},'DateSetMethod','Intersection');
end
merge_count = merge_count + 1;
end
% ANALYSE PORTFOLIO
Returns=tick2ret(Port);
q = Portfolio;
q = q.estimateAssetMoments(Returns)
[qassetmean, qassetcovar] = q.getAssetMoments
This is probably due to merge. By default, it sorts columns alphabetically. Unfortunately, as your naming pattern is "FundN", this means that, for example, Fund10 will normally be sorted before Fund9. So as you're looping over I from 5 to 19, you will have Fund10, through Fund19, followed by Fund4 through Fund9.
One way of solving this would to be always use zero padding (Fund01, Fund02, etc) so that alphabetical order and numerical order are the same. Alternatively, force it to stay in the order you read/merge the data by setting SortColumns to 0:
Port = merge(Port,Fundts{I},'DateSetMethod','Intersection','SortColumns',0);
is there a command of Matlab to get the number of the written rows in excel file?
firstly, I fill the first row. and then I want to add another rows in the excel file.
so this is my excel file:
I tried:
e = actxserver ('Excel.Application');
filename = fullfile(pwd,'example2.xlsx');
ewb = e.Workbooks.Open(filename);
esh = ewb.ActiveSheet;
sheetObj = e.Worksheets.get('Item', 'Sheet1');
num_rows = sheetObj.Range('A1').End('xlDown').Row
But num_rows = 1048576, instead of 1.
please help, thank you!
If the file is empty, or contains data in only one row, then .End('xlDown').Row; will move to the very bottom of the sheet (1048576 is the number of rows in a Excel 2007+ sheet).
Test if cell A2 is empty first, and return 0 if it is.
Or use Up from the bottom of the sheet
num_rows = sheetObj.Cells(sheetObj.Rows.Count, 1).End('xlUp').Row
Note: I'm not sure of the Matlab syntax, so this may need some adjusting
You can use MATLAB's xlsread function to read in the spreadsheet. This obtains the following fields:
[numbers strings misc] = xlsread('myfile.xlsx');
if you do a size check on strings or misc, this should give you the following:
[rows columns] = size(strings);
testing this, I got rows = 1, columns = 10 (assuming nothing else was beyond 'A' in the spreadsheet).