Что я делаю здесь, так это для поиска в Excel-листе значения, если значение совпадает, оно будет заменено первым значением в данном текстовом файле:

пример:

поиск по значению текста найти первый экземпляр заменить на первое значение в данном текстовом файле, который "читается", поиск снова для текста найти снова заменить на "чтение", пока не может найти "текст", теперь искать второе значение в массиве "text1", поиск в листе Excel, найти его заменить второй строкой в данном текстовом значении, которое является "read1" и так далее.

У меня есть сценарий, который работает несколько, проблема в том, что он заменит все значения массива только первой строкой текстового файла, который "читается", он не перебирает вторую строку текстового файла.

Может кто-нибудь, пожалуйста, помогите.

код:

Файл test.txt читается как:

читать

READ1

read2

$text = "text","text1","text2","text3"
$replace=get-content C:\script\test.txt
$File = "C:\script\test.xlsx"

# Setup Excel, open $File and set the the first worksheet
$i=0
$Excel = New-Object -ComObject Excel.Application
$Excel.visible = $true
$Workbook = $Excel.workbooks.open($file)
$Worksheets = $Workbooks.worksheets
$Worksheet = $Workbook.Worksheets.Item(1)
$Range = $Worksheet.Range("A1","Z10").EntireColumn

Foreach($SearchString in $text){
$Search = $Range.find($SearchString)

if ($search -ne $null){

$SearchString
$replace[$i]

$FirstAddress = $search.Address
do {
        $Search.value() = $replace[$i]
        $search = $Range.FindNext($search)

    } while ( $search -ne $null -and $search.Address -ne $FirstAddress )

$i++
}

 }
$WorkBook.Save()
$WorkBook.Close()
[void]$excel.quit()

1 ответ1

0

Я думаю, что проблема в том, что по умолчанию он ищет "текст" в любом месте ячейки, который соответствует "тексту", "тексту1", "тексту2" и т.д. Вы можете изменить порядок вещей так, чтобы "текст" был последним, который он ищет. для, но это не идеально. На самом деле, нам нужно, чтобы он соответствовал всей ячейке.

К счастью, в Range есть параметр.Find(), которая позволяет нам сделать именно это: LookAt (https://msdn.microsoft.com/en-us/library/office/ff839746.aspx).

К сожалению, доступ к именованным параметрам в COM-объектах в PowerShell немного затруднителен, поэтому проще всего просто указать предыдущие параметры:

$First = $Worksheet.Range("A1")    
$Search = $Range.find($SearchString,$First,-4163,1)

$ First - это A1, -4163 - это значение перечисления для просмотра значений, а 1 - это значение перечисления для целого.

Взаимодействие PS-COM для Excel очень требовательно к типам данных. Там, где я обычно ожидал, что смогу выбрать первую ячейку из диапазона и передать ее функции, это не похоже на это, поэтому я указал ее вручную в $ First.

Я просмотрел перечисления и жестко запрограммировал их, потому что это еще одна неприятная вещь в PowerShell - надеюсь, кто-нибудь сможет предложить хороший способ сделать это.

Таким образом, весь сценарий оказывается:

$text = "text","text1","text2","text3"
$replace=get-content C:\script\test.txt
$File = "C:\script\test.xlsx"

# Setup Excel, open $File and set the the first worksheet
$i=0
$Excel = New-Object -ComObject Excel.Application
$Excel.visible = $true
$Workbook = $Excel.workbooks.open($file)
$Worksheets = $Workbooks.worksheets
$Worksheet = $Workbook.Worksheets.Item(1)
$Range = $Worksheet.Range("A1","Z10").EntireColumn
$First = $Worksheet.Range("A1")

Foreach($SearchString in $text){
$Search = $Range.find($SearchString,$First,-4163,1)

if ($search -ne $null){

$SearchString
$replace[$i]

$FirstAddress = $search.Address
do {
        $Search.value() = $replace[$i]
        $search = $Range.FindNext($search)

    } while ( $search -ne $null -and $search.Address -ne $FirstAddress )

$i++
}

 }
$WorkBook.Save()
$WorkBook.Close()
[void]$excel.quit()

Он запомнит настройки поиска для вызовов FindNext(), поэтому нет необходимости что-либо там менять.

Надеюсь, это поможет!

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .