【问题标题】:Delphi 7 with..do statement doesen't work with variant variableDelphi 7 with..do 语句不适用于变体变量
【发布时间】:2023-04-09 18:55:01
【问题描述】:

我正在通过 Delphi 7 使用 Microsoft Excel。它工作正常,但在格式化行和范围时,我必须编写这么长的字符串。

XLApp.Workbooks[1].WorkSheets[NameDoc].Range['A19:L19'].Font.Bold := true;

所以我想摆脱繁重的工作并通过像这样的“with..do”语句来完成它

with XLApp.Workbooks[1].WorkSheets[NameDoc] do
begin
  Range['A19:L19'].Font.Bold := true;
end;

但是在编译阶段我看到了这个错误

Record, object or class type required

在字符串上 - “with..do”。

我以这种方式创建 Excel 对象

XLApp: Variant;
XLApp := CreateOleObject('Excel.Application');

我认为 with..do 语句不适用于变体类型变量,但我想知道我是否正确?如果我是对的,是否有任何解决方法可以让它发挥作用?

【问题讨论】:

    标签: excel delphi with-statement


    【解决方案1】:

    with 可以与Variant 一起使用吗?

    没有。

    您可以将with 用于其成员在编译时已知的类型。但在运行时评估. 运算符的变体不属于这一类。因此with 不适用于变体。

    documentation 强调说:

    with 语句是引用记录字段的简写 或对象的字段、属性和方法。的语法 with 声明是:

    with obj do statement
    

    或:

    with obj1, ..., objn do statement
    

    其中 obj 是产生对 记录、对象的引用的表达式 实例、类实例、接口或类类型(元类) 实例,而语句是任何简单或结构化的语句。

    【讨论】:

    • 谢谢。我在猜测,但我想要证据。
    • 尽管我偏爱 WITH,但我知道 DCC 中关于接口的文档和可预测的 ARC 有多么少,我宁愿避免使用 with loooong 多点 COM 表达式。
    【解决方案2】:

    Variant 可以是任何东西,也可以什么都不是——编译器不知道也不知道:它就是所谓的“动态类型值”。因为它不知道——它不知道是否会有任何成员(属性、方法)以及是否有——它们会有什么名字。

    为了获得强大的编译时类型的好处——包括使用with,但不仅如此——你必须使用接口变量,那些由 TExcelApplication 组件和具有这些值“静态类型”的底层单元提供的变量——因此让 Delphi 编译器在编译时,在运行之前知道值类型。该单元中有很多类型,如 iWorsksheet、iRange 等。

    但是,由于这与引用计数和生命周期有关,我建议您显式使用临时变量,而不是使用 with 和隐式不可见变量。由于您无法控制它们的寿命和间隙,因此您以后可能会在某个意想不到的地方碰壁。我做到了。

    var tmpR: iRange; // assuming we have statically-typed API
    // for example - providing we using ExcelXP or Excel2000 unit
    
    tmpR := XLApp.Workbooks[1].WorkSheets[NameDoc];
    
    tmpR.Range['A19:L19'].Font.Bold := true; // instead of with
    
    with tmpR do // also possible but gives little benefit now
    begin        //    when we made a dedicated temp var
      Range['A19:L19'].Font.Bold := true;
    end;
    
    tmpR := nil; // crucial unless the most short and simplistic functions
    // just release hold on Excel's object - let it manage its memory freely,
    // by letting Excel know your program no more uses that object.
    

    另请阅读

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-15
      • 2010-10-27
      • 2020-11-09
      • 1970-01-01
      相关资源
      最近更新 更多