2013-08-30 3 views
1

я работаю над созданием сценария, который я приведу список библиотек документов SharePoint 2007, на который будет делать следующее:Excel & Powershell: Bulk Найти и заменить URL, используемый в формулах

  1. В Excel, найти формулы в пределах ячеек, которые ссылаются на другие книги + листы (XLS/XLSX)
  2. Если найдено, замените формулу ссылку http://serverold/site/doclib/ с http://servernew/sites/sitecollection/doclib и сохранить
  3. Else, закройте книгу и перейти на следующий Log полного URL и имя файла любые изменения

Использование кода на этой link в моей отправной точки я не могу получить следующую работу:

  1. Регулярное выражение выражение, чтобы сделать сценарий обнаружения URL в формулах
  2. изменить сценарий, чтобы заменить старый путь с новым путем в формуле внутри ячеек.
  3. для каждого ветви иметь дело с тем, когда обнаруживается совпадение (сохранить и закрыть), и когда он не нашел (только близко)

Я не вдаваясь в подробности о всех исследований I» (информация очень светлая на земле), просто упоминается в другом потоке, что вы можете перечислить эти ссылки централизованно в Excel, но ни один пример или ссылки не были указаны, и когда я попытался перечислить links collection в 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() 

Спасибо всем, кто может помочь и за ваше время , Bests, Ash

+0

+1 большой вопрос. – brettdj

ответ

2

Считаете ли вы, используя просто:

$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 \ а \

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) 

Fun начинается:

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 ничего не будет делать и $ изменены = $ формула
  • Если нет, верните новую формулу.

Конечно, вам не нужно использовать -replace это не единственным способ, но вы получите идею ...

Надеются, что это помогает!

+0

Привет, Адиль, спасибо. Это устранило проблему. Ты звезда. – AshFlaw

+0

Как вы пишете адрес? Я пытаюсь $ _Address = $ _. Address.Replace ("http: // old", "http: // new"), и он не принимает. –

+0

@MatthewMcDermott Этот человек уже ответил и закрыл 2 года назад. Задайте новый вопрос и опубликуйте свой код + вопрос. –

Смежные вопросы