使用 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 添加图表的解决方案。我找到的关于此主题的任何帖子都已过时或无用。
总结,我的问题是:
- 如何使用 Matlab(使用通用的最新 ActiveX 代码结构)在 Excel 中插入图表。
- 如何 select XValue 和 YValues(范围)的列
- 如何访问图表标题、坐标轴、线条外观和图例
我正在使用 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
我有大约 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 添加图表的解决方案。我找到的关于此主题的任何帖子都已过时或无用。
总结,我的问题是:
- 如何使用 Matlab(使用通用的最新 ActiveX 代码结构)在 Excel 中插入图表。
- 如何 select XValue 和 YValues(范围)的列
- 如何访问图表标题、坐标轴、线条外观和图例
我正在使用 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