How to recalculate cell content in gui table using other cell content of the same table just like excel?
1 次查看(过去 30 天)
显示 更早的评论
Hi
I would like to ask a question. Using guide I create a gui table (4*3) with tag uitable1. I want matlab to do calculation on third column when the user enters numbers to first column by its own without using pushbutton. For example user enters 2 6 5 9 to column 1 and matlab automatically adds 10 to each number and shows 12 16 15 19 to the third column just like excel. I tried to write codes to
function uitable1_CellEditCallback(hObject, eventdata, handles)
olddata=get(handles.uitable1,’Data’);
newdata(:,3)=olddata(:,1)+10;
set(handles.uitable1,'data',newdata);
but unfortunately it does not work.
The error is:
Undefined operator '+' for input arguments of type 'cell'.
...
...
It would be appreciated if you could help.
Regards
Kourosh
回答(1 个)
Jan
2018-3-11
编辑:Jan
2018-3-12
The error message is clear already: The variable olddata is a cell array, but you can apply the addition to numerical data only.
dataC = get(handles.uitable1, 'Data');
data = cell2mat(dataC(:, 3)) + 10;
dataC(:, 3) = num2cell(data);
% [EDITED] There way a typo in the names of the variables
By the way: You used ’ as quote, but in Matlab you need '. They look almost identical, but have different ASCII codes.
17 个评论
Kourosh Sharifi
2018-3-11
编辑:Kourosh Sharifi
2018-3-11
Thank you very much for your kind comment but I still couldn' slove the problem. In fact I don't know where exactly to insert your codes. I had tried before to use cell2mat and num2cell but didn't work. If possible please write complete script.
Thanks a lot before
Jan
2018-3-12
编辑:Jan
2018-3-12
Replace
function uitable1_CellEditCallback(hObject, eventdata, handles)
olddata=get(handles.uitable1,’Data’);
newdata(:,3)=olddata(:,1)+10;
set(handles.uitable1,'data',newdata);
by
function uitable1_CellEditCallback(hObject, eventdata, handles)
dataC = get(handles.uitable1, 'Data');
data = cell2mat(dataC(:, 3)) + 10;
dataC(:, 3) = num2cell(data);
set(handles.uitable1, 'Data', dataC);
Does it work? If not, please post a copy of the complete error message.
Kourosh Sharifi
2018-3-12
编辑:Kourosh Sharifi
2018-3-12
Hi This is my complete script:
function uitable1_CellEditCallback(hObject, eventdata, handles)
% hObject handle to uitable1 (see GCBO) % eventdata structure with the following fields (see MATLAB.UI.CONTROL.TABLE)
% Indices: row and column indices of the cell(s) edited
% PreviousData: previous data for the cell(s) edited
% EditData: string(s) entered by the user % NewData: EditData or its converted form set on the Data property. Empty if Data was not changed
% Error: error string when failed to convert EditData to appropriate value for Data
% handles structure with handles and user data (see GUIDATA)
dataC = get(handles.uitable1, 'Data');
data = cell2mat(dataC(:,3))+10;
dataC(:,3)= num2cell(data);
set(handles.uitable1,'Data',dataC);
and this is the complete error message:
Subscripted assignment dimension mismatch.
Error in tablecal>uitable1_CellEditCallback (line 89) dataC(:,3)= num2cell(data);
Error in gui_mainfcn (line 95) feval(varargin{:});
Error in tablecal (line 42) gui_mainfcn(gui_State, varargin{:});
Error in matlab.graphics.internal.figfile.FigFile/read>@(hObject,eventdata)tablecal('uitable1_CellEditCallback',hObject,eventdata,guidata(hObject)) Error while evaluating Table CellEditCallback.
By the way, the porpose is to add 10 to each cell of column 1 and display the result in column 3 but you didn't mention column 1 in your codes. Shouldn't be the second line:
data(:,3) = cell2mat(dataC(:,1))+10;
instead?
Thanks again
Jan
2018-3-13
Of course this looks better:
data(:,3) = cell2mat(dataC(:,1)) + 10;
if you want to add 10 to the elements of the first column.
Please use the debugger to find the reason of the error. Set a breakpoint in the failing line and run the code again. Then check the dimensions:
class(dataC)
size(dataC)
size(dataC(:,3))
size(num2cell(data))
It is not clear to me, what the problem is.
Kourosh Sharifi
2018-3-13
编辑:Kourosh Sharifi
2018-3-13
Ok. Thank you. I just want to know if this works on your Matlab? Did you try it? My matlab version is R2017b.
Jan
2018-3-15
I've tried it successfully:
dataC = {2,3,4; 5,6,7} % Example data
data = cell2mat(dataC(:, 1)) + 10
dataC(:, 3) = num2cell(data)
If you get a "Subscripted assignment dimension mismatch" error, please use the above mentioned method to examine the problem. If you post the output of the shown commands, the forum can help you to solve the problem.
Kourosh Sharifi
2018-3-15
编辑:Kourosh Sharifi
2018-3-15
I think I’d better to explain more. First of all, honestly I am new to matlab and I only know some basics about it. I have an excel file which includes too many entries and does relatively complex calculations. That file consists of many sheets and tables and data of tables relate(depend) each other using calculation which excel does. For example the user enters data to one cell and some calculation occur on another cell of the same table or other tables immediately on its own using formula or VBA. Now what I am going to do is to write a program by matlab to achieve the same result. In the excel file the user enters data which will defer up to the situation of the job. My question is that is matlab basically suitable for such a purpose? If so, I have to use tables (using guide) so that the content of the cells of the tables could depend each other. Obviously tables will not be the only part of the program and I will need slider, pop-up menu, edit text, static text, etc as well. But unfortunately I’ve suck in this step of the table and couldn’t find how to relate value of the cell of a table to each other. And it is very important that the user enters value to the table as an entry.
Warm regards
Kourosh
Jan
2018-3-16
@Kourosh: Your original question was:
newdata(:,3) = olddata(:,1)+10;
ERROR: Undefined operator '+' for input
arguments of type 'cell'.
And it is answered by
newdata = olddata;
newdata(:,3) = num2cell(cell2mat(olddata(:,1)) + 10);
Does this solve the problem?
Now you are asking a new question, but it does not get clear to me. Of course you can write some code, which relates the elements of a uitable object with each other - see the given example: Whenever an element of the uitable is modified, the formula is applied (here the 3rd column is the 1st column + 10). What is the problem with expanding this example to your needs?
Kourosh Sharifi
2018-3-16
编辑:Kourosh Sharifi
2018-3-16
Hi
With that explanation I just wanted to infrom why I need such a table.
About your previous example:
function uitable1_CellEditCallback(hObject, eventdata, handles)
dataC = {2,3,4;5,6,7} data = cell2mat(dataC(:,1))+10 dataC(:,3) = num2cell(data)
when I run the script the table is created and once I enter any number anywhere in the table, the result will be displayed to the command window.
dataC =
2×3 cell array
{[2]} {[3]} {[4]}
{[5]} {[6]} {[7]}
data =
12
15
dataC =
2×3 cell array
{[2]} {[3]} {[12]}
{[5]} {[6]} {[15]}
I does not solve my problem since it is for specific numbers (2 & 3) and does not matter what number I enter in the table.
About your recent code:
function uitable1_CellEditCallback(hObject, eventdata, handles)
olddata = get(handles.uitable1,'Data'); newdata=olddata; newdata(:,3) = num2cell(cell2mat(newdata(:,1))+10); set(handles.uitable1,'Data',newdata);
when I run this script, table is created and any first numbers that I enter to the table in coulmun 1 an irrelevent number like 62 appears in column 3 and from now on if I enter any numbers in the coulmn 1, this error appears:
Subscripted assignment dimension mismatch.
Error in tablecal>uitable1_CellEditCallback (line 88) newdata(:,3) = num2cell(cell2mat(newdata(:,1))+10);
Error in gui_mainfcn (line 95) feval(varargin{:});
Error in tablecal (line 42) gui_mainfcn(gui_State, varargin{:});
Error in matlab.graphics.internal.figfile.FigFile/read>@(hObject,eventdata)tablecal('uitable1_CellEditCallback',hObject,eventdata,guidata(hObject)) Error while evaluating Table CellEditCallback.
Now If I change the codes like this:
function uitable1_CellEditCallback(hObject, eventdata, handles)
dataC = get(handles.uitable1,'Data'); data(:,3) = cell2mat(dataC(:,1))+10; dataC = num2cell(data); set(handles.uitable1,'Data',dataC);
There will be no error but:
1- When I enter any numbers to column 1 the table which is already 4*3 will be converted to 1*3 and again an irrelevant number like 64 appears to column 3.
2- From now on, any numbers which I enter to column 1, the sum of this number and 10 will be calculated and diplayed in column 3 (something I need) but number in column 1 changes to zero!!!
3- It does not work for number zero.
Please suppose my codes are all wrong. If possible you please kindly create a table using guide (only using guide not using uitable function) and wirte your script to do something I need without using pushbutton (column 3 becomes (column 1) +10) then run it on your matlab if you make sure it works please kindly give me a copy of that and I will try it as well.
Thanks a lot for your time and consideration.
Jan
2018-3-18
@Kourosh Sharifi: "I does not solve my problem since it is for specific numbers (2 & 3) and does not matter what number I enter in the table." -- Then I still do not understand, what you are asking for. Of course it matters, which values you insert in the table and I have no idea why you assume, that something (what) is for the specific numbers 2 and 3.
"when I run this script, table is created and any first numbers that I enter to the table in coulmun 1 an irrelevent number like 62 appears in column 3 and from now on if I enter any numbers in the coulmn 1, this error appears: ..." -- I asked you already to provide the required details to debug this. You did not answer my question for clarifications yet.
The difference between the codes is just another name for the variable and if it is expressed in 2 or 3 lines of code. You should be able to debug this and adjust the names of the variables to your needs.
To get help, please post your complete code and ask a specific question.
Kourosh Sharifi
2018-3-18
编辑:Kourosh Sharifi
2018-3-18
Hi
As I told you I am new to MatLab, so I don't know what is the right way for debugging. But I tried to debug the following codes by running them line by line (I converted the dash lines at the left side of codes to red circle then run the script):
function uitable1_CellEditCallback(hObject, eventdata, handles)
olddata = get(handles.uitable1,'Data'); newdata=olddata; newdata(:,3) = num2cell(cell2mat(olddata(:,1))+10); set(handles.uitable1,'Data',newdata);
It shows line 1 to 3 are being run ok but the last line gets error. and the error is:
Subscripted assignment dimension mismatch.
Error in tablecal>uitable1_CellEditCallback (line 88) newdata(:,3) = num2cell(cell2mat(olddata(:,1))+10);
Error in gui_mainfcn (line 95) feval(varargin{:});
If this way of debugging is wrong and if I should do anything else please let me know.
thanks
Jan
2018-3-18
Hi, you can let Matlab stop automatically, when an error occurs. Type this in the command window:
dbstop if error
Now run the code again until the error is reached. Then check the types and sizes of the variables by typing this in the command window:
class(olddata)
size(olddata)
class(newdata)
size(newdata)
I have no idea, how this code could fail with the shown error message. If olddata is a matrix instead of a cell, or an empty cell, other messages are shown.
Kourosh Sharifi
2018-3-19
Hi,
I entered statements in the command window and this is the result:
>> dbstop if error >> tablecal Subscripted assignment dimension mismatch.
Error in tablecal>uitable1_CellEditCallback (line 88) newdata(:,3) = num2cell(cell2mat(olddata(:,1))+10);
Error in gui_mainfcn (line 95) feval(varargin{:});
Error in tablecal (line 42) gui_mainfcn(gui_State, varargin{:});
Error in matlab.graphics.internal.figfile.FigFile/read>@(hObject,eventdata)tablecal('uitable1_CellEditCallback',hObject,eventdata,guidata(hObject)) 88 newdata(:,3) = num2cell(cell2mat(olddata(:,1))+10); K>> class(olddata)
ans =
'cell'
K>> size(olddata)
ans =
4 3
K>> class(newdata)
ans =
'cell'
K>> size(newdata)
ans =
4 3
K>>
It seems both size and class of olddata and newdata are the same, but still it gives error (shouldn't they have numerical class?). Generally speaking I'm surprised why such a simple relationship between data in a table should be such time consuming and hard to solve. And again why nobody could solve it (I asked some friends). Maybe I am going all the way wrong from beginning?!
Thanks
Jan
2018-3-19
@Kourosh Sharifi: I assume, the problem can be solved in seconds, if an experienced programmer could use the debugger directly. It would very useful, if you post the contents of the variables, because all I can do currently is blind guessing.
The data of the uitable are stored as cell to allow to define the columns with different types of values, e.g. strings or check-boxes. See: doc uitable.
This is the failing code:
olddata = get(handles.uitable1,'Data');
newdata = olddata;
newdata(:,3) = num2cell(cell2mat(olddata(:,1))+10);
You have checked already, that the variables have the expected types. The next step is to find out, which part of the command causes the problem. Split the command into parts:
newdata = olddata;
c1 = olddata(:,1)
c2 = cell2mat(c1)
c3 = c2 + 10
c4 = num2cell(c3)
newdata(:,3) = c4
Which line fails? It works as expected for the test data:
olddata = {2,3,4; 5,6,7}
If this works on your machine also, find out, what the difference is between these test data and the data of your uitable.
You have mentioned strange values like 62 or 64. I do not have any idea, where they are coming from. Again the only chance to find the source of these values is to use the debugger. If you are not familiar with using the debugger, it is time to learn how to use it, see https://www.mathworks.com/help/matlab/debugging-code.html and https://www.mathworks.com/help/matlab/matlab_prog/debugging-process-and-features.html. All I can do with blind guessing in the forum, can be done with real data by your own much more efficiently on your machine.
I've posted the example and you replied, that it works without an error:
dataC = {2,3,4; 5,6,7} % Example data
data = cell2mat(dataC(:, 1)) + 10
dataC(:, 3) = num2cell(data)
Of course this does not consider the contents of the table, but all you have to change is to replace the example data by this contents and insert the new data afterwards:
% dataC = {2,3,4; 5,6,7} % Example data
dataC = get(handles.uitable1, 'Data')
data = cell2mat(dataC(:, 1)) + 10
dataC(:, 3) = num2cell(data)
set(handles.uitable1, 'Data', dataC);
I do not think, that I can help any further here.
Kourosh Sharifi
2018-3-19
Hi,
Spilitting the variables gives this result:
function uitable1_CellEditCallback(hObject, eventdata, handles) % hObject handle to uitable1 (see GCBO) % eventdata structure with the following fields (see MATLAB.UI.CONTROL.TABLE) % Indices: row and column indices of the cell(s) edited % PreviousData: previous data for the cell(s) edited % EditData: string(s) entered by the user % NewData: EditData or its converted form set on the Data property. Empty if Data was not changed % Error: error string when failed to convert EditData to appropriate value for Data % handles structure with handles and user data (see GUIDATA) olddata = get(handles.uitable1,'Data'); newdata=olddata; c1=olddata(:,1); c2=cell2mat(c1); c3=c2+10; c4=num2cell(c3); newdata(:,3)=c4; set(handles.uitable1,'Data',newdata);
After running I entered 8 to the first row of column 1 and this is the result (all rows of column 3 becomes 66 which is nonsense):
c1 =
4×1 cell array
{'8' }
{0×0 char}
{0×0 char}
{0×0 char}
c2 =
'8'
c3 =
66
c4 =
1×1 cell array
{[66]}
newdata =
4×3 cell array
{'8' } {0×0 char} {[66]}
{0×0 char} {0×0 char} {[66]}
{0×0 char} {0×0 char} {[66]}
{0×0 char} {0×0 char} {[66]}
c1 =
4×1 cell array
{'8' }
{'6' }
{0×0 char}
{0×0 char}
c2 =
2×1 char array
'8'
'6'
c3 =
66
64
c4 =
2×1 cell array
{[66]}
{[64]}
And once I enter any number in second row of column 1 error comes:
Subscripted assignment dimension mismatch.
Error in tablecal>uitable1_CellEditCallback (line 92) newdata(:,3)=c4;
Error in gui_mainfcn (line 95) feval(varargin{:});
Error in tablecal (line 42) gui_mainfcn(gui_State, varargin{:});
Error in matlab.graphics.internal.figfile.FigFile/read>@(hObject,eventdata)tablecal('uitable1_CellEditCallback',hObject,eventdata,guidata(hObject)) 92 newdata(:,3)=c4;
Class of data are:
K>> class(olddata)
ans =
'cell'
K>> class(c1)
ans =
'cell'
K>> class(c2)
ans =
'char'
K>> class(c3)
ans =
'double'
K>> class(c4)
ans =
'cell'
K>> class(newdata)
ans =
'cell'
and in the workspace we have:
name: c1, c2, c3, c4, eventdata, handles, hObject, newdata, olddata
Value: 4x1 cell, 2x1 char, [61;60], 2x1 cell, 1x1 CellEditData, 1x1 struct, 1x1 Table, 4x3 cell, 4x3 cell
That example {2,3,4;5,6,7} works because they are pure numbers and like any other calculator it adds 10 to each number and then displays them. I still think the problem could be in the type of data. If you run this on your matlab you will see all of them.
Thanks
Jan
2018-3-20
@Kourosh Sharifi: Ah! The data are char vectors, not numbers. Then their ASCII codes are used instead of the values.
You need a str2double in addition.
% dataC = {'2','3','4'; '5','6','7'}
dataC = get(handles.uitable1, 'Data')
data = str2double(dataC(:, 1)) + 10
dataC(:, 3) = sprintfc('%g', data)
set(handles.uitable1, 'Data', dataC);
sprintfc is the same as sprintf, but creates a cell array. Unfortunately this very useful function is not documented and could be removed in the future. But it existed in Matlab for at least 18 years now, such that I expect it to be available in the future also. To be sure, you could use your own function:
function C = sprintfc_(Fmt, D)
C = cell(size(D));
for k = 1:numel(D)
C{k} = sprintf(Fmt, D(k));
end
end
Kourosh Sharifi
2018-3-20
编辑:Kourosh Sharifi
2018-3-24
Hi,
Appreciate. It completely works. I was disapointed and decided not continue discussing. But you helped me a lot proffesionally and patiently. I hope this useful function will remain.
Thanks again
Kourosh
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Workspace Variables and MAT-Files 的更多信息
标签
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!发生错误
由于页面发生更改,无法完成操作。请重新加载页面以查看其更新后的状态。
您也可以从以下列表中选择网站:
如何获得最佳网站性能
选择中国网站(中文或英文)以获得最佳网站性能。其他 MathWorks 国家/地区网站并未针对您所在位置的访问进行优化。
美洲
- América Latina (Español)
- Canada (English)
- United States (English)
欧洲
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)
亚太
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)