1

我正在创建一个脚本,我将提供一个 SharePoint 2007 文档库列表,这些文档库将执行以下操作:

  1. 在 Excel 中,在链接到其他工作簿 + 工作表 (XLS/XLSX) 的单元格中查找公式
  2. 如果找到,请将公式链接替换为http://serverold/site/doclib/http://servernew/sites/sitecollection/doclib保存
  3. 否则,关闭工作簿并移至下一个记录所有更改的完整 URL 和文件名

使用此链接上的代码 作为我的起点,我无法进行以下工作:

  1. 使脚本检测公式中的 URL 的正则表达式
  2. 修改脚本以将旧路径替换为单元格内公式中的新路径。
  3. a为每个分支处理何时找到匹配项(保存并关闭)和未找到匹配项(仅关闭)

我不会详细介绍我所做的所有研究(信息非常简单),只是在另一个线程中提到您可以在 Excel 中集中枚举这些链接,但没有给出示例或链接,并且当我尝试在 PowerShell(安装了 Excel 2010)中枚举链接集合时,我正在使用的示例工作簿是空的,我在这个意义上将其称为“链接”。

枚举链接集合的示例:

$File = "C:\temp\example.xls"
$Excel = New-Object -ComObject Excel.Application
$Excel.visible = $true
$Workbook = $Excel.workbooks.open($file)
$Workbook.LinkSources

所以这就引出了一个问题,哪种方法是正确的?

示例 Excel 公式

=+'http://server.old/site/site/Work in Progress `enter code here`Documents/Statements/[Hierarchy2011.xls]Reports'!$AD$37+'http://server.old/site/site/Work in Progress Documents/

枚举链接的脚本(从我提到的链接作为我的起点) -

$path = "C:\temp"
$excelSheets = Get-Childitem -Path $path -Include *.xls,*.xlsx -Recurse
$excel = New-Object -comobject Excel.Application
$excel.visible = $false

foreach($excelSheet in $excelSheets)
{
 $workbook = $excel.Workbooks.Open($excelSheet)
 "There are $($workbook.Sheets.count) sheets in $excelSheet"

 For($i = 1 ; $i -le $workbook.Sheets.count ; $i++)
 {
  $worksheet = $workbook.sheets.item($i)
  "`tLooking for links on $($worksheet.name) worksheet"
  $rowMax = ($worksheet.usedRange.rows).count
  $columnMax = ($worksheet.usedRange.columns).count
  For($row = 1 ; $row -le $rowMax ; $row ++)
  {
   For($column = 1 ; $column -le $columnMax ; $column ++)
    { 
     [string]$formula = $workSheet.cells.item($row,$column).formula
     if($formula -match "\w?:\\\w*\\\[\w*\.xls\w?\]") {"`t`t$($formula)"}
    } #end for $column
   } #end for $row
  $worksheet = $rowmax = $columnMax = $row = $column = $formula = $null
 } #end for
 $workbook.saved = $true
 $workbook.close()
} #end foreach

 $excel.quit()
 $excel = $null
 [gc]::collect()
 [gc]::WaitForPendingFinalizers()

感谢任何可以提供帮助的人和您的时间。最好的,灰

4

1 回答 1

4

你会考虑简单地使用:

$formula -replace 'http://server.old/','http://server.new/'

更新:我最初认为您对正则表达式有问题(仅),但通读该脚本,我认为您需要更多帮助。

让我来看看相关的代码部分:

For($i = 1 ; $i -le $workbook.Sheets.count ; $i++)
 {
  $worksheet = $workbook.sheets.item($i)
  "`tLooking for links on $($worksheet.name) worksheet"
  $rowMax = ($worksheet.usedRange.rows).count
  $columnMax = ($worksheet.usedRange.columns).count
  For($row = 1 ; $row -le $rowMax ; $row ++)
  {
   For($column = 1 ; $column -le $columnMax ; $column ++)
    { 
     [string]$formula = $workSheet.cells.item($row,$column).formula
     ## This is irrelavant, it's trying to match a file...
     ##     if($formula -match "\w?:\\\w*\\\[\w*\.xls\w?\]") {"`t`t$($formula)"}

     $changed = $formula -replace 'http://server.old/','http://server.new/'
     if ($formula -ne $changed) {
        $workSheet.cells.item($row,$column).formula = $changed
     }


    } #end for $column
   } #end for $row
  $worksheet = $rowmax = $columnMax = $row = $column = $formula = $null
 } #end for

 ## The line below is actually cause file to be not saved when closing it as you are telling excel, hey you are saved.
 ## $workbook.saved = $true
 ## I would use this:
 if (!$Workbook.saved) { $workbook.save() }
 $workbook.close()
} #end foreach

现在,当我讨论这个时,让我告诉你在尝试修改其他人的脚本之前我将如何调查这项业务: 在控制台中调查对象!

对于此示例,我在 c:\temp\a\ 中创建了一个简单的电子表格 (a2.xls)

PS H:\> $excel = New-Object -com Excel.Application
PS H:\> $workbook = $excel.Workbooks.Open("C:\temp\a\a2.xls")
PS H:\> $worksheet=$workbook.Sheets.item(1)

有趣的开始:

PS H:\> $worksheet |get-member -Type Properties


   TypeName: System.__ComObject#{000208d8-0000-0000-c000-000000000046}

Name                              MemberType Definition
----                              ---------- ----------
Application                       Property   Application Application () {get}
AutoFilter                        Property   AutoFilter AutoFilter () {get}
AutoFilterMode                    Property   bool AutoFilterMode () {get} {set}
Cells                             Property   Range Cells () {get}
CircularReference                 Property   Range CircularReference () {get}
CodeName                          Property   string CodeName () {get}
Columns                           Property   Range Columns () {get}
Comments                          Property   Comments Comments () {get}
ConsolidationFunction             Property   XlConsolidationFunction ConsolidationFunction () {get}
ConsolidationOptions              Property   Variant ConsolidationOptions () {get}
ConsolidationSources              Property   Variant ConsolidationSources () {get}
Creator                           Property   XlCreator Creator () {get}
CustomProperties                  Property   CustomProperties CustomProperties () {get}
DisplayAutomaticPageBreaks        Property   bool DisplayAutomaticPageBreaks () {get} {set}
DisplayPageBreaks                 Property   bool DisplayPageBreaks () {get} {set}
DisplayRightToLeft                Property   bool DisplayRightToLeft () {get} {set}
EnableAutoFilter                  Property   bool EnableAutoFilter () {get} {set}
EnableCalculation                 Property   bool EnableCalculation () {get} {set}
EnableFormatConditionsCalculation Property   bool EnableFormatConditionsCalculation () {get} {set}
EnableOutlining                   Property   bool EnableOutlining () {get} {set}
EnablePivotTable                  Property   bool EnablePivotTable () {get} {set}
EnableSelection                   Property   XlEnableSelection EnableSelection () {get} {set}
FilterMode                        Property   bool FilterMode () {get}
HPageBreaks                       Property   HPageBreaks HPageBreaks () {get}
Hyperlinks                        Property   Hyperlinks Hyperlinks () {get}
Index                             Property   int Index () {get}

(缩短输出)。看到那里的超链接属性吗?你指的是那个吗?看一看:

PS H:\> $worksheet.hyperlinks


Application   : Microsoft.Office.Interop.Excel.ApplicationClass
Creator       : 1480803660
Parent        : System.__ComObject
Name          : http://old.server/adil1/hellow
Range         : System.__ComObject
Shape         :
SubAddress    :
Address       : http://old.server/adil1/hellow
Type          : 0
EmailSubject  :
ScreenTip     :
TextToDisplay :

您看不到我的来源,但让我告诉您:它正在从公式中提取 URL。所以,如果我更改姓名和地址... 不幸的是,我不能。我实际上可以将地址更改为指向新服务器,但它的“名称”属性是只读的(请参阅它没有设置):

PS H:\> $worksheet.hyperlinks |gm


   TypeName: System.__ComObject#{00024431-0000-0000-c000-000000000046}

Name              MemberType Definition
----              ---------- ----------
Address           Property   string Address () {get} {set}
Name              Property   string Name () {get}

这就是为什么你可能会更好:

  • 将单元格的内容读取为字符串,
  • 仅替换服务器名称
  • 如果单元格没有你要找的东西 -replace 不会做任何事情并且 $changed = $formula
  • 如果没有,请立即返回新公式。

当然,你不需要使用 -replace 不是唯一的方法,但你明白了......

希望这可以帮助!

于 2013-08-30T16:41:10.990 回答