【问题标题】:Problems parsing Excel 2010 .xlsx file with Win32::OLE in Perl在 Perl 中使用 Win32::OLE 解析 Excel 2010 .xlsx 文件时出现问题
【发布时间】:2012-03-13 01:25:50
【问题描述】:

我有一个 excel 文件 (.xlsx) 连接到带有 .iqy 文件的“数据源”。我使用 Perl 打开 excel 文件并刷新数据。最初,我的代码有效。但是,我需要更改我的电子表格链接到的 .iqy 文件,这样做似乎破坏了我的 Perl 脚本(尽管实际上并没有更改脚本本身的任何内容)。现在当我打电话时它失败了

my $LastRow = $Sheet->UsedRange->Find({What=>"*",
    SearchDirection=>xlPrevious,
    SearchOrder=>xlByRows})->{Row};

并且 cmd 输出显示:“不能在 shared.pl 第 20 行使用未定义的值作为 HASH 引用。”我已经尝试过调试,但我对 Win32::OLE 模块的内容知之甚少,无法知道如何在调试器中捕捉问题发生的位置或原因。我的脚本的源代码是:

#!/usr/bin/perl
use Win32::OLE;
use Win32::OLE qw(in with);
use Win32::OLE::Variant;
use Win32::OLE::Const 'Microsoft Excel';

$Excel = Win32::OLE->GetActiveObject('Excel.Application') ||
       Win32::OLE->new('Excel.Application');
$Excel->{'Visible'} = 0;        #0 is hidden, 1 is visible
$Excel->{DisplayAlerts}=0;  #0 is hide alerts

# Open File and Worksheet
my $Book = $Excel->Workbooks->Open ('C:\shareP\sp.xlsx'); # open Excel file
$Sheet = $Book->Worksheets(1);

# Refresh Data (ActiveWorkbook.RefreshAll)
$Book->RefreshAll();

# Find Last Column and Row
my $LastRow = $Sheet->UsedRange->Find({What=>"*",
    SearchDirection=>xlPrevious,
    SearchOrder=>xlByRows})->{Row};

my $LastCol = $Sheet->UsedRange->Find({What=>"*", 
              SearchDirection=>xlPrevious,
              SearchOrder=>xlByColumns})->{Column};
####### EDIT: I initially didn't post this portion because it stops
#       before reaching it unless I make $LastCol and $LastRow constants
my @hasher;
my $c = "a";
for (my $cn=1; $cn <= $LastCol; $cn++){
    for (my $r=2; $r <= $LastRow; $r++){
# stops here with same error if I make $LastCol and $LastRow constants
        $hasher[$r-2]{ $Sheet->Range($c.'1')->{Value} } = $Sheet->Range($c.$r)->{Value};
    }
$c++;
}
####### end of EDIT
# Save as Excel
$Book->Save();  
$Book->Close();
$Excel->Quit();  

提前感谢您的任何建议。我真的被这个卡住了。

【问题讨论】:

    标签: perl excel-2010 xlsx win32ole


    【解决方案1】:

    我相信你的 find 函数现在没有返回值。我有两种可能的解释。

    1) 也许您的新源数据不再包含“*”字符

    2) find 函数会记住使用之间的一些属性,即LookInLookAtSearchOrder。为获得最佳结果,您应始终在查找时设置这 3 个属性,以确保获得所需的功能。

    我的建议是尝试在电子表格上手动执行查找,看看它是否有效。我认为您的错误不在脚本的 OLE 部分。

    【讨论】:

    • Find "*" 在手动完成时适用于电子表格。在 save() 和 close() 之前,我还有更多的代码,因为它在到达它之前就停止了,所以我删除了这些代码。我尝试将“$LastRow”和“$LastCol”变量设为常量,但随后代码因同样的错误而停得更远。 (请参阅我在帖子中添加的内容,对不起,我一开始就把它遗漏了)。但是,如果我以 $LastRow 和 $LastCol 作为常量运行代码两次,它在第二次运行时工作......我看到的唯一区别是,在第二次运行中,excel 仍然从​​第一次运行开始打开,因为它没有t 到达 close()。
    • 鉴于您的其他信息...我猜这个问题与$Sheet 为空有关。尝试通过文本名称而不是数字来引用工作表,看看是否有帮助
    【解决方案2】:

    我通过在代码中添加一个短暂的暂停来解决问题。 perl 脚本在 excel 工作表完成刷新之前正在推进。感谢您的帮助。

    【讨论】:

      【解决方案3】:

      我认为这是因为你们中的一个电子表格是空的。 获取总列数和行数的更好方法是:

      my $Tot_Rows= $Sheet->UsedRange->Rows->{'Count'}; 
      
      my $Tot_Cols= $Sheet->UsedRange->Columns->{'Count'}; 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-11-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-04-06
        • 1970-01-01
        相关资源
        最近更新 更多