You can either use struct arrays with dynamic field names, as @Shai and @RobertStettler suggest.
However, another option is a table. This might be more appealing if you want to see your data in one big matrix, and you can give each table row the name of your variables too! Note that the rows in a table would then be what you call your variables, but MATLAB calls the table columns its variables.
Also note that using a table can be more difficult than using struct or cell arrays, but if you know how to use them, you can handle a table too.
An example:
% create dummy data
rowNames = {'a';'b';'c'};
M = {ones(3); zeros(3); nan(3)}; % a cell, one element per item in rowNames
V = [1 2; 3 4; 5 6]; % a matrix of vectors, each row containing a vector for every item in rowNames
% create a table
T = table(M,V,'RowNames',rowNames); % this is where your variable names could go
Now, to access data you could use (some examples):
T(2,:) or T('b',:), return a table for all data on the 'b' row.
T(:,2) or T(:,'V'), return a table of variable V for all rows.
T.V or T{:,2} or T{:,'V'} or T.(2), return matrix V for all rows. This syntax is similar to accessing a (dynamic) field name of a struct.
T{3,1} or T{'c',1} or T.M('c'), return cell M for row 'c'. This syntax is similar to accessing a cell, but with more advanced possibilities, i.e. the ability to access the table via row or variable names.
T{3,1}{:} or T{'c',1}{:} or T.M{'c'}, return cell contents M for row 'c'.
And even more complex: T('a',:).M{:} is a complex way of accessing the cell content of M for row 'a', which can be done with T{1,1}{:} or T.M{'a'} or T{'a','M'}{:} or T.M{1} as well.
In your case you would en up with a 40x3 table, with every row what you call a variable and the first column the matrices (in cell arrays), and the last two columns the vectors (as well in cell arrays or as a 40xm double, m being the length of your vector).
ABC(i).dataMatrix. It is not clear why you would have to useeval.