使用 Matlab 使用范围内的 X 和 Y 值创建 Excel 个图表

Using Matlab to create Excel charts with X and Y values from range

我有大约 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:$B')); %% here an error occurs 

错误:

Error using COM.Excel_Application/Range. Object returned error code: 0x800A03EC"

我还没有找到任何通过 Matlab 中的 ActiveX object 添加图表的解决方案。我找到的关于此主题的任何帖子都已过时或无用。


总结,我的问题是:


我正在使用 Excel 2016 和 Matlab R2017a。


编辑:

这周我开发了一个自己的解决方案,它仍然不能完美运行,但接近我想要的。你能不能也看看这段代码:

重要的是图表 1。我想将 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;

发生另一个错误:

Error using Interface.000208D8_0000_0000_C000_000000000046/Range

Error: Object returned error code: 0x800A03EC

Error in CodeTestmy (line 13) chart1.SetSourceData(wb.Worksheets.Item('Tabelle1').Range('$B:$B, $H:$P'));


现在这个问题差不多有了答案。有关更多错误相关的答案,请查看

正如我在评论中所建议的,更好的记录方法是使用 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;

你的错误:

您在尝试访问 Excel 应用程序的 Range 对象时遇到错误。这不存在!所有 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 ...

输出图表sheet并输入"Sheet1":


编辑:

在上面,我遍历 numbers 列来填充 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