#excel #powershell #if-statement #cell #copy-paste
#преуспеть #powershell #if-оператор #ячейка #копировать-вставить
Вопрос:
У меня есть электронная таблица с 2 столбцами дат, в каждом из которых только одно значение даты в каждой строке. Наличие двух столбцов для этого является избыточным для моих целей, поэтому я хотел бы запустить сценарий powershell, чтобы проверить каждую ячейку в столбце Date2 и, если она пуста, скопировать значение Date1 из той же строки в столбец Date2. Это та часть, с которой я не могу разобраться; Чтобы проверить все ячейки в столбце Date2 и, если они пусты, скопируйте соседнее значение Date1. Как только это будет сделано, я удалю столбец Date1. ПРИМЕЧАНИЕ: Столбец Date2 содержит больше дат, поэтому используйте его в качестве основного столбца для сохранения (меньше копирования / вставки). ТИА
Example Test.xlsx:
A B
1 | Date1 | Date2 |
2 | 01/01/1900 | |
3 | 01/01/1900 | |
4 | | 01/01/1900 |
5 | | 01/01/1900 |
6 | 01/01/1900 | |
7 | | 01/01/1900 |
$Excel = New-Object -Com Excel.Application -Property @{Visible = $false} # Start Excel and hide the window
$Excel.DisplayAlerts = $False # Disable comfirmation prompts
$Workbook = $Excel.Workbooks.Open(C:TempTest.xlsx) # Open spreadsheet file
#This is the part I'm stuck on:
#If cell in column Date2 is empty, then copy the adjacent Date1 value to the Date2 cell - This is done until at the end of the columns
[void]$Workbook.Sheets.Item("Test").Cells.Item(1, 1).EntireColumn.Delete() # Deleting "Date1" column
$Workbook.Save() # Save changes
$Workbook.Close($true) # Close workbook
$Excel.Quit() # Quit Excel
[Runtime.Interopservices.Marshal]::ReleaseComObject($Excel) # Release COM
Ответ №1:
Все, что вам нужно в вашем коде, это перебирать строки и обновлять ячейку в столбце 2 (B), если она пуста, значением столбца 1 (A).
Попробуйте
$Excel = New-Object -Com Excel.Application -Property @{Visible = $false} # Start Excel and hide the window
$Excel.DisplayAlerts = $False # Disable comfirmation prompts
$Workbook = $Excel.Workbooks.Open("D:TestTest.xlsx") # Open spreadsheet file
$Sheet = $Workbook.Worksheets.Item("Test")
# get the total number of rows in the sheet
$rowCount = ($Sheet.UsedRange.Rows).Count
# update cell values in a loop
for ($row = 1; $row -le $rowCount; $row ) {
$value = $Sheet.Cells.Item($row, 2).Text
if ([string]::IsNullOrWhiteSpace($value)) {
# copy the cell format first; then the value
$Sheet.Cells.Item($row, 2).NumberFormat = $Sheet.Cells.Item($row, 1).NumberFormat
$Sheet.Cells.Item($row, 2) = $Sheet.Cells.Item($row, 1)
}
}
[void]$Sheet.Cells.Item(1, 1).EntireColumn.Delete() # Deleting "Date1" column
$Workbook.Save() # Save changes
$Workbook.Close($true) # Close workbook
$Excel.Quit() # Quit Excel
# clean up COM objects
$null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($Sheet)
$null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($Workbook)
$null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($Excel)
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()
Комментарии:
1. Привет, Тео, это сработало, спасибо, но даты, которые копировались, потеряли свой формат даты; 01/01/1900 скопировано как ‘1’. Знаете ли вы, как установить ячейку в формате даты?
2. Я понял! Я добавил дополнительную строку в конце инструкции if в цикле for: $Sheet . Ячейки. Элемент ($ row, 2).NumberFormat = «д / ММ / гггг» # Только один ‘d’, чтобы избавиться от начальных нулей. Мне нужно протестировать в январе, чтобы подтвердить, требуется ли остальная часть моего кода M или MM для месяца. Приветствия
3. @S.Hampton Я обновил код, чтобы также скопировать исходный формат номера ячейки. Это делает его более универсальным, и вам не нужно самостоятельно определять, что это за формат, методом проб и ошибок. Приветствия!
Ответ №2:
Это повторяющаяся задача? В противном случае использование функций Excel может быть более быстрым.
В любом случае, для обработки данных Excel я настоятельно рекомендую использовать модуль ImportExcel