使用Matlab创建范围为

时间:2017-06-13 09:27:59

标签: excel matlab charts com activex

我有大约20列数据,每行约20,000行。所有计算都在Matlab中完成,然后创建图表。

不幸的是,我需要将整个输出放在Excel文件中,包括几个可编辑的图表。使用xlswrite我创建了Excel文件,现在我正在努力按照我想要的方式创建图表。

我尝试使用此代码,但遇到了几个错误,无法选择图表的X和Y值。

 Excel = actxserver('Excel.Application');  
 WB = Excel.workbooks.Open('D:\...\Test.xlsx');
 Charts = WB.Charts; 
 Chart = invoke(Charts,'Add');
 invoke(Chart, 'SetSourceData', Excel.Range('Sheet1!$B$2:$B$16')); %% here an error occurs 

错误:

  

使用COM.Excel_Application / Range时出错。对象返回错误代码:0x800A03EC“

我无法找到任何通过Matlab中的ActiveX对象添加图表的解决方案。我在这个主题上找到的任何帖子都已过时或无用。

摘要,我的问题是:

  • 如何使用Matlab在Excel中插入图表(使用一般的,最新的ActiveX代码结构)。
  • 如何选择XValue和YValues(范围)
  • 的列
  • 如何访问图表标题,轴,线条外观和图例

我正在使用Excel 2016和Matlab R2017a。

修改

在这个星期我开发了一个自己的解决方案,但仍然没有完美的工作,但接近我想要的。您能否看一下这段代码:

重要的是只有chart1。我想将 XValue设置为B列,将 YValues设置为sheet1(Tabelle1)的H - P 列。

%%%%% general Code to insert a Chart in Excel using Matlab %%%%%
%% start Excel and open Workbook
excel = actxserver('Excel.Application');
wb = excel.Workbooks.Open('C:\...\Test.xlsx');
%% makes the created sheet visible
excel.Visible = true;
%% add 1. Chart
chart1 = wb.Charts.Add;
%% set source data 
chart1.SetSourceData(wb.Worksheets.Item('Tabelle1').Range('$B:$B, $H:$P')); % 'Tabelle1' is the german equal to sheet1, my excel is german
%% Name chart sheet
chart1.Name = '1. TestChart';
%% Set chart title,  see https://msdn.microsoft.com/en-us/library/office/ff196832.aspx
chart1.HasTitle = true;
chart1.ChartTitle.Text = 'Test Title';
%% Set chart types,  see https://msdn.microsoft.com/en-us/library/office/ff837417.aspx
chart1.ChartType = 'xlXYScatterSmoothNoMarkers';
%% Set chart legend, see https://msdn.microsoft.com/en-us/library/office/ff821884.aspx
chart1.HasLegend = true;
%% Set Axes Titles
chart1.Axes(1).HasTitle = true;
chart1.Axes(1).AxisTitle.Text = 'Time [s]'; % XAxes
chart1.Axes(2).HasTitle = true;
chart1.Axes(2).AxisTitle.Text = 'Temperature[°C]'; %YAxes
%% add 2nd chart
chart2 = wb.Charts.Add([], chart1); %place after chart1
chart2.SetSourceData(wb.Worksheets.Item('Tabelle1').Range('$B:$B, $Q:$Q'));
% ... same procedure as above

%% use to quit all open Excel processes
% excel.Quit;

发生另一个错误:

  

使用Interface.000208D8_0000_0000_C000_000000000046 / Range

时出错      

错误:对象返回错误代码:0x800A03EC

     

CodeTestmy中的错误(第13行)   chart1.SetSourceData(wb.Worksheets.Item('Tabelle1')。Range('$ B:$ B,$ H:$ P'));

现在这个问题几乎已经回答了。有关进一步的错误相关答案,请查看related question

1 个答案:

答案 0 :(得分:0)

正如我在评论中所建议的那样,更好的文档化方法是使用VBA。实际上,VBA文档实际上可以用来消除直接从Matlab与COM对象交互的大部分猜测,因为语法类似。

这是一些更新的Matlab代码,可以实现您的三点。我在适当的地方包含了MSDN文档的链接:

% Start Excel and open workbook
Excel = actxserver('Excel.Application');  
WB = Excel.Workbooks.Open('C:\...\test.xlsx');
% Show the workbook
Excel.visible = 1;
% Add chart
Chart = invoke(WB.Charts,'Add');
% Get Sheet object
SheetObj = Excel.Worksheets.get('Item', 'Sheet1');
% Name chart sheet
Chart.Name = 'TestChart';

% Set source data range of chart
% X and Y data can also be set to Matlab arrays, by Srs.Values and Srs.XValues, ensuring equal length
  % Y data
Srs = Chart.SeriesCollection.Add(SheetObj.Range('B2:B16'));
  % X data, could be a Matlab array of correct length
Srs.XValues = SheetObj.Range('A2:A16');
  % Series name
Srs.Name = 'Test Series';

% For chart types,  see https://msdn.microsoft.com/en-us/library/office/ff837417.aspx
Chart.ChartType = 'xlXYScatterSmooth'; 
% Set chart title,  see https://msdn.microsoft.com/en-us/library/office/ff196832.aspx
Chart.HasTitle = true;
Chart.ChartTitle.Text = 'Test Title';
% Set chart legend, see https://msdn.microsoft.com/en-us/library/office/ff821884.aspx
Chart.HasLegend = true;

您的错误:

您遇到错误,因为您尝试访问Range应用程序的Excel对象。这不存在!所有Range个对象都属于Sheet对象,这是我在上面的代码中首先检索的对象。

创建多个系列:

你说你有很多数据列,这是一种通过循环包含它们的方法。它还会在每列中找到最后使用的行。

% ... CREATE WORKBOOK / CHART AS BEFORE ...
%
Chart.Name = 'TestChart';

% Set source data range of chart, do X and Y data for each series    
columns = 2:4;
colnames = {'xdata', 'my series 1', 'my series 2', 'my series 3'};
for col = columns
      % Get Excel column *letter* from column *number*
    colchar = strrep([char(96+floor((col-1)/26)) char(97+rem(col-1,26))],char(96),'');
      % Last row of data, see https://msdn.microsoft.com/en-us/library/office/ff839539.aspx
      % Data must be contiguous (no gaps / blank cells)
    lastrow = num2str(SheetObj.Range([colchar, '2']).End('xlDown').Row);
      % Y data, creating range strings by concatenation of column character and row number
    Srs = Chart.SeriesCollection.Add(SheetObj.Range([colchar, '2:', colchar, lastrow]));
      % X data, same approach is used for last row, but only column = 1 = "A" 
    Srs.XValues = SheetObj.Range(['A2:A', lastrow]);
     % Set column name, to use the first row do
     % Srs.Name = SheetObj.Range([colchar, '1']);
    Srs.Name = colnames{col};
end

Chart.ChartType = 'xlXYScatterSmooth'; 
%
% ... TITLE / LEGEND AS BEFORE ...

输出图表表并输入“Sheet1”:

example

编辑:

在上面,我遍历列数字以填充y数据。如果你知道列字母,那么你可以循环colchar而不是创建它。

% There are shortcuts to creating a cell array of consecutive letters, 
% Like columnletters = cellstr(('H':'J')');
for colchar = {'H', 'I', 'J'};
    % ... same as the above for loop, but don't need to get colchar from col
    lastrow = num2str(SheetObj.Range([colchar, '2']).End('xlDown').Row);
    Srs = Chart.SeriesCollection.Add(SheetObj.Range([colchar, '2:', colchar, lastrow]));
    Srs.XValues = SheetObj.Range(['A2:A', lastrow]);
    Srs.Name = SheetObj.Range([colchar, '1']);

end