无法访问Range对象的Range方法; COM限制?

时间:2018-04-11 19:06:09

标签: matlab excel-vba com vba excel

在Excel VBA编辑器的立即窗口中,我可以执行以下操作:

?ActiveSheet.Range("C3:D4").Range("C3:D4").Address
$E$5:$F$6

根据一些简单的测试,这似乎没有在Matlab中做出相同的反应。以下是为测试设置COM接口的代码:

excel = actxserver('Excel.Application');
excel.Visible=1;
wbks = excel.Workbooks;
wbks.Add
sht = wbks.Item(1).Sheets.Item(1)

%
%     Run some range tests
%

try
   excel.DisplayAlerts = 0; % Forgo save prompt on Close
end; try
   wbk.Close
end; try
   excel.Quit % Excel process still present
end; try
   delete(excel) % Excel process disappears
end % try

现在,如果sht是一个Worksheet对象,我会收到以下错误:

K>> o=sht.Range('C3:D4')
    o = Interface.Microsoft_Excel_14.0_Object_Library.Range

K>> o.Range('C3:D4').Address

    Cannot find an exact (case-sensitive) match for 'Range'
    The closest match is: range in C:\Program Files\MATLAB\Single_R2015b\toolbox\stats\stats\range.m
    Did you mean: K>> o.range('C3:D4').Address

这是一个错误的函数,因为range具有非大写r是内部Matab函数。因此,我按下Ctrl-C来突破(否则,它会抱怨不兼容的参数)。

要解决无法识别Range的原因,请检查是方法还是属性。通过COM访问时,Range是一种方法而不是属性:

K>> methods(o)
    Methods for class Interface.Microsoft_Excel_14.0_Object_Library.Range:
        <...snip...>
        PrintPreview            Table
        Range                   TextToColumns
        RemoveDuplicates        UnMerge
        <...snip...>

这进一步表明Range不是属性(即使它在VBA中):

K>> get(o)
         <...snip...>
     QueryTable: 'Error: Object returned error code: 0x800A03EC'
         Resize: [1x1 Interface.Microsoft_Excel_14.0_Object_Library.Range]
            Row: 3
         <...snip...>

由于属性按字母顺序列出,Range会在QueryTable之后显示,如果它被识别为属性。但是,它并未在上述结果中列出。

作为替代诊断步骤,我尝试使用点表示法(Range)访问o.Range。不幸的是,Matlab似乎得到了自己的原生函数range,它与Excel Range无关。

所以那些诊断工作......

问题

对于给定的Range对象,如何访问Range方法(由COM识别) Range属性(如它在VBA文档中有描述)?

所感

通过COM接口访问Range属性和方法时似乎存在许多差异。在立即窗口中,可以使用Offset属性(它被描述为属性):

? ActiveSheet.Range("C3:D4").Offset(2,3).Address
$F$5:$G$6

过度COM,而不是那么多,即使get(o)显示Offset是一个返回范围的有效属性:

K>> o=sht.Range('C3:D4')
    o = Interface.Microsoft_Excel_14.0_Object_Library.Range
K>> o=o.Offset(2,2)
Index exceeds matrix dimensions.

1 个答案:

答案 0 :(得分:0)

这是我通过反复试验达到的解决方案,并在Matlab技术支持的帮助下进行了改进:

调用get作为方法,然后提供所需的属性名称。它适用于属性Offset

K>> o = sht.Range('C3:D4')
    o = Interface.Microsoft_Excel_14.0_Object_Library.Range
K>> o.get('Offset',2,3).Address
    ans = $F$5:$G$6

它也适用于Range

K>> o = sht.Range('C3:E5')
    o = Interface.Microsoft_Excel_14.0_Object_Library.Range
K>> o.get('Range','B2:C3').Address
    ans = $D$4:$E$5

奇怪的是Range是一种根据COM的方法(但是根据Excel VBA文档的属性)。尽管在通过COM访问时被视为一种方法,但需要使用get而不是invoke来调用它。后者产生错误:

K>> o.invoke('Range','B2:C3').Address
    Error using Interface.Microsoft_Excel_14.0_Object_Library.Range/invoke.
    Cannot find an exact (case-sensitive) match for 'Range'.
    The closest match is: range in C:\Program Files\MATLAB\Single_R2015b\toolbox\stats\stats\range.m