How can I write an excel file using the timer on MATLAB?

2 views (last 30 days)
I'm trying to write data to excel only once at the end using a timer on MATLAB.
There are two things I want to do :
1) When I execute the program which I written referring to the sample code below, I get an error and I have no idea how to fix the error.
2) Currently, the values ​​of x_value and y_value are displayed without using the disp () function, but I want to prevent this from being displayed.
Error message
>> timer_sample
x_value =
1 2 3
y_value =
4 5 6
x_value =
1 2 3 7 8 9
y_value =
4 5 6 10 11 12
Error while evaluating TimerFcn for timer 'timer-1'
Error: Invalid expression. Check for missing multiplication operator, missing or unbalanced delimiters, or other syntax error. To construct matrices, use brackets instead of parentheses.
Program which I executed
global x_value
global y_value
time = timer('TimerFcn', 'stat=false; disp(''Timer!'') filename = ''data.xlsx''; x_range = ''sender''; y_range = ''receiver''; xlswrite(filename, x_value, x_range) xlswrite(filename, y_value, y_range) exit();', 'StartDelay', 30);
start(time)
%flag to write code after 30 seconds
global stat
stat = true;
x_value = [x_value [1 2 3]]
y_value = [y_value [4 5 6]]
x_value = [x_value [7 8 9]]
y_value = [y_value [10 11 12]]
What I tried to
Without the time, I am sure that excel output is available like the below.
global x_value
global y_value
global stat
stat = true;
x_value = [x_value [1 2 3]]
y_value = [y_value [4 5 6]]
x_value = [x_value [7 8 9]]
y_value = [y_value [10 11 12]]
filename = 'data.xlsx';
x_range = 'sender';
y_range = 'receiver';
xlswrite(filename, x_value, x_range)
xlswrite(filename, y_value, y_range)
  2 Comments
Adam
Adam on 10 May 2019
Edited: Adam on 10 May 2019
That's an absolutely horrible way to define a function (multiple lines all in a single string). It would be much easier for you to see what is wrong (and more readable, less brittle in general) to just define it as a function and pass the handle to that function in. Nevertheless, without trying it, I suspect you are simply missing the ; off the end of disp(''Timer!'') in the function string and also later on after the first xlswrite.
You are also missing ; off the end of your x_value and y_value lines which is why they print to the command line.
I would also strongly advise against using global variables, there is pretty much nothing that can't be done better with just proper variables passed around between functions as arguments.
Jan
Jan on 10 May 2019
Edited: Jan on 10 May 2019
Adam hits the point.
XLSX files are zipped files. They are a very bad choice for appending data dynamically, because the unpacking and repacking requires an exponentially growing amount of time. Prefer appending data to a binary or text file and convert the data at the end to an XLSX file.

Sign in to comment.

Answers (1)

Guillaume
Guillaume on 10 May 2019
Edited: Guillaume on 11 May 2019
As others have said, defining the timer function as a string is the worst way of doing it. You get no syntax highlighting, no tab completion, no way of debugging code. It's a recipe for bugs, as your case proves. So define that timer callback as a proper function.
Personally, since you also want to pass data to that callback, I'd go OOP and wrap that in a class. This also avoids the dreaded global variables:
classdef TimerCallback < handle
properties %public properties
state;
x_value;
y_value;
filename;
end
methods
%constructor
function this = TimerCallback(filename)
if nargin > 0
this.filename = filename;
end
this.state = true;
end
%callback function
function callback(this, ~, ~)
%consider using writetable instead of xlswrite. At least, use only one xlswrite.
xlswrite(this.filename, this.x_value, 'sender');
xlswrite(this.filename, this.y_value, 'receiver');
this.state = false;
disp('Callback executed');
end
end
end
Your script is then:
mycallback = TimerCallback('data.xlsx');
mytimer = timer('TimerFcn', @mycallback.callback, 'StartDelay', 30);
start(mytimer);
mycallback.x_value = [mycallback.x_value, [1 2 3]];
mycallback.y_value = [mycallback.y_value, [4 5 6]];
mycallback.x_value = [mycallback.x_value, [7 8 9]];
mycallback.y_value = [mycallback.y_value, [10 11 12]];
%and so on... until the Timer completes
  6 Comments
horizon
horizon on 11 May 2019
I have no windows environment now and executed your code on Mac.
I've got the following result and any excel file was not created.
Should I try it on Windows environment?
>> timer_sample
Warning: Unable to write to Excel format, attempting to write file to csv format. To write to an Excel file, convert your data to a table and
use writetable.
> In xlswrite (line 179)
In TimerCallback/callback (line 20)
In timer_sample>@(varargin)mycallback.callback(varargin{:})
In timer/timercb (line 34)
In timercb (line 24)
Warning: Unable to write to Excel format, attempting to write file to csv format. To write to an Excel file, convert your data to a table and
use writetable.
> In xlswrite (line 179)
In TimerCallback/callback (line 21)
In timer_sample>@(varargin)mycallback.callback(varargin{:})
In timer/timercb (line 34)
In timercb (line 24)
Callback executed
Guillaume
Guillaume on 13 May 2019
Yes, as documented xlswrite can only write excel files on a Windows computer with Excel installed.
On a MAC, you can use writetable, or since R2019a, writematrix to write excel files on non-windows computers.

Sign in to comment.

Products


Release

R2017a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!