【问题标题】:Why is perl saving two copies of Excel spreadsheet?为什么 perl 保存两份 Excel 电子表格?
【发布时间】:2016-10-15 15:39:24
【问题描述】:

这类似于A copy of Excel Addin is created in My Documents after saving,只是我使用的是Perl而不是VBA,使用xls文件而不是xlsm,并且行为的负面影响是不同的。

我继承了一个在 Windows 2003 Server 上作为 SYSTEM 运行的 Perl 脚本 (Perl 5.8.8)。将 Excel 2003 模板文件复制到唯一的、完全定义的路径位置后,它会使用 OLE 在 Excel 中打开唯一文件,编辑文件,保存文件,然后关闭文件。结果是编辑后的文件既保存在正确的、完全定义的路径位置,也保存在默认用户配置文件的 Documents 文件夹中。

这会导致数千个此类文件堆积在 C: 驱动器上,因为每位新入职的管理员都会在其 Documents 文件夹中获得一份副本。

添加设置 $OUT 值的代码:

if (!$db->Sql("EXEC GetDetails 'name'"))
{
    while ($db->FetchRow()>0)
    {
        @DataIn = $db->Data();
        $name = $DataIn[0];
        $IN = $DataIn[1];
        $OUT = $DataIn[2];
        opendir(DIR,"$OUT") || die "$OUT directory does not exist $!\n";

        #... loop of proprietary code
            #...
            @Completed = $db1->Data();
            #...

            &formatExcelReport  #The code that I previously posted

            #...
            # more proprietary code
        # end of loop

    } #end of while
}#end of if

我最初发布的代码:

# Initialize Excel object
eval {Win32::OLE->new('Excel.Application', 'Quit')};
eval {$Excel = Win32::OLE->GetActiveObject('Excel.Application')};
unless (defined $Excel)
{
    $Excel = Win32::OLE->GetActiveObject('Excel.Application')
             || Win32::OLE->new('Excel.Application', 'Quit');
}
$infiles = "Report_Template.xls";
$infiles = $OUT."/".$infiles;
$db6->Sql("EXEC FormatResults '".$Completed[0]."','".$Completed[1]."'");
$row = 2;
$fileName = $Completed[0]."_".$Completed[1];
$uniquefile = $fileName.$printdate.".xls";

# $OUT is a fully defined path on the E: drive
$reportfile = "$OUT"."\\".$uniquefile;
copy($infiles,$reportfile);
$Book = $Excel->Workbooks->Open("$reportfile");
$sheetnum = 1;
my $Sheet = $Book->Worksheets($sheetnum);

# Set Headers
$Header = $Sheet->PageSetup->{'CenterHeader'};
$Header = $Header." Results Test Code: ".$Completed[0]." Worksheet: ".$Completed[1]." Date: ".$headerdate;
$Sheet->PageSetup->{'CenterHeader'}= $Header;

# More file editing
# ...

$Book->Save();
$Book->Close(0);
Win32::OLE->new('Excel.Application', 'Quit');

这个问题的根源是 Save() 命令吗?我应该改用 SaveAs() 吗?

也欢迎就 Excel 的使用方式提供任何其他反馈。

谢谢!

【问题讨论】:

    标签: excel perl save windows-server-2003 ole


    【解决方案1】:

    我不知道是什么导致了这种行为,但这里有一些可以尝试的方法。

    • 模板和复制它的文件有名字

        $infiles = $OUT."/".$infiles;
        $reportfile = "$OUT"."\\".$uniquefile;
      

    使用相同的分隔符。

    • 尝试禁止一些可能的设置,指示制作另一个副本。或许

        $Excel->Application->{CreateBackup} = 0;
      

    但是,这可能不是正确的属性——在 VB 或 Excel 文档中搜索可能导致 Excel 保存额外副本的属性。 (不必是“备份”。)

    • 尝试创建一个新文件并使用SaveAs作为测试,看看你是否再次得到两个文件。模板复制可能会将其设置为Save 一个额外的副本(即使我不知道如何)。我会说要么就是这样,要么是一些需要关闭的常规设置。

    剩下的就是原帖,关于使用SaveAs,我以为是创建了一个新文件

    您将使用SaveAs 来编写一个新文件。见saveas in MSDN library

    将对工作簿的更改保存在不同的文件中。

    使用save method 可能会出于某种原因保存两个文件,如answer by Borodin 中所述。该页面还建议使用SaveAs 来创建新文件

    第一次保存工作簿时,使用 SaveAs 方法指定文件的名称。

    一旦你改为使用SaveAs,应该会出现一个确认对话框来处理。如果你想抑制,你可以设置一个属性,一个(或任何一个?)

    $Excel->Application->{DisplayAlerts} = 0;
    # or
    $Excel->{DisplayAlerts} = 0;
    

    有关许多选项,例如备份,请参阅OLE automation in PERL in a Nutshell 章节。


    关于其他一些资源的说明。 this post on perlmonks 中有一本各种各样的食谱。 this SO post 中给出了各种操作的列表。

    最后,我不知道使用 OLE 的原因有多深,但如果只是写一些 Excel 文件,还有其他模块。例如备受推崇的Spreadsheet::WriteExcelExcel-Writer-XLSX

    【讨论】:

    • @Rebeccah 在意识到您发布的代码打开了现有文件而不是创建新文件后,我大幅更新了答案。请告诉我进展如何。
    • 谢谢你,@zdim。模板文件中包含所有格式。我今天要做一个测试部署,所以我将有机会尝试其中的一些东西。新版本将使用 Spreadsheet::WriteExcel 或可能是 SpreadSheet::ParseExcel::SaveParser (我有两个版本要试用),但这种当前的行为一直困扰着我,所以我希望我能深入了解它。
    • 我已经更新了我的问题,以纠正 Excel 正在创建新文件的错误印象,而事实上,它正在打开现有文件。
    • @Rebeccah 是的,当然。所以你需要那个。我相应地更改了我的帖子。仍然值得尝试使用新文件,只是看看你是否得到相同的行为。除此之外,我猜这是一些 Excel 设置。我认为所有项目符号都值得尝试,但如果您只是编写 Excel 文件,请使用其他模块,尤其是第一个推荐的模块。其他用途需要 OLE,你不需要它来写一个或几个文件(除非有非常花哨的元素)。
    • 正确。我认为脚本最初是这样编写的,因为当时作者并不知道其他模块——我不确定它们是否存在于 Perl 5.8 中。 ....为什么这个界面会从​​我给你的评论中删除@zdim?
    【解决方案2】:

    这是非常奇怪的 Perl 代码。 eval 事后不检查 $@ 是错误的——您需要知道代码的某个步骤是否失败,以使以下步骤有意义

    看起来问题出在您对copy($infiles, $reportfile) 的调用中。这将保存文件的一个副本,而$Book->Save$Book->Close 将保存另一个

    【讨论】:

    • 不过,我仍然没有关注一件事——哪个副本最终位于默认用户的 Documents 文件夹中? $reportfile 应该是复制时和在 Excel 中打开文件时 E: 驱动器上 .xls 文件的完整路径名。
    • 关于 eval 的使用,我认为这是在 Internet 上发现的一些技巧,以防止脚本在 Excel 已打开的情况下退出 - 而是导致使用现有的 Excel 实例。我认为由于其他原因,这被证明是一个坏主意。我们这个脚本的下一个版本根本不会使用 OLE 和 Excel。但就目前而言,我只想了解为什么它的行为方式如此。
    • @Rebeccah:请在您的原始问题中添加任何相关信息,不要删除已经存在的信息。我们可能会接受更改,但您可以发表评论以提醒我们您已进行更改
    • @Rebeccah:请同时删除所有不再相关的 cmets
    • @Rebeccah:编辑链接在您的问题下方,就在标签下方。 Here's a copy
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-15
    • 1970-01-01
    • 2015-12-11
    • 2012-12-22
    • 2011-10-17
    • 1970-01-01
    相关资源
    最近更新 更多