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

さて、私がこれに取り組んでいる間に、他の誰かのスクリプトを変更しようとする前に、このビジネスを調査する方法を教えてください: コンソールでオブジェクトを調査してください!

この例では、単純なスプレッドシート (a2.xls) を c:\temp\a\ に作成しました。

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 に答える