powershell - вставьте данные в Excel - PullRequest
2 голосов
/ 28 апреля 2011

Сегодня я только что собрал этот скрипт powershell, который

  • принимает текстовый файл с разделителями табуляции,

  • читает это в память,

  • создает переменное число запросов фильтра на основе различных значений определенного столбца

  • создает новую пустую книгу Excel

  • добавляет каждое из подмножеств фильтруемых данных в новый лист Excel

Последний шаг, где я застрял. В настоящее время мой код помещает несколько строк данных в диапазон на листе в форме развернутых / транспонированных записей «ключ: значение», что приводит к горизонтальному расположению данных. Один и тот же диапазон данных всегда перезаписывается.

Мне нужны данные в виде вертикальной компоновки, то есть данные в столбцах, точно так же, как если бы файл CSV был импортирован с помощью мастера импорта файлов из MS Excel.

Есть ли более простой способ сделать это, чем ниже?

Признаюсь, некоторые функции powershell вставлены сюда в режиме культового культа. Пожалуйста, обратите внимание, что у меня нет опыта PowerShell вообще. Несколько лет назад я написал несколько пакетных файлов, vbscript и vba. Итак, другие критические замечания также приветствуются.

PARAM (
    [Parameter(ValueFromPipeline = $true)] 
    $infile = ".\04-2011\110404-13.txt"
)

PROCESS {
  echo " $infile"
  Write-Host "Num Args:"  $args.Length;


 $xl = New-Object -comobject Excel.Application;
 $xl.Visible = $true;

 $Workbook = $xl.Workbooks.Add();

 $content = import-csv -delimiter "`t" $infile ;
 $ports = $content  | select-object Port# | sort-object Port#  -Unique -Descending;
 $ports | ForEach-Object {
    $p = $_;
    Write-Host $p.{Port#};

    $Worksheet = $Workbook.Worksheets.Add();
    $workSheet.Name = [string]::Format( "{0} {1}", "PortNo" ,  $p.{Port#});
    $filtered = $content | where-object {$_.{Port#} -eq $p.{Port#}  };
    $filtered |  ForEach-Object { 
        Write-Host $_.{ObsDateTime} , $_.{Port#}
    }
    $filtered | clip.exe;
    $range =  $Workbook.ActiveSheet.Range("a2", "a$($filtered.count)");
    $Workbook.ActiveSheet.Paste($range, $false);     

 }

 $xl.Quit() 

}

Пример вывода данных

НЕВЕРНО

Port#       : 1
Obs#        : 1
Exp_Flux    : 0,99
IV Cdry     : 406.96
IV Tcham    : 16.19
IV Pressure : 100.7
IV H2O      : 9.748
IV V3       : 11.395
IV V4       : 0.759
IV RH       : 53.12

RIGHT

Port#   Obs#    Exp_Flux    IV Cdry IV Tcham    IV Pressure IV H2O  IV V3   IV V4   IV RH
1     1 0,99    406.96  16.19   100.7   9.748   11.395  0.759   53.12

Ответы [ 3 ]

2 голосов
/ 28 апреля 2011

Я использовал функцию $Workbook.ActiveSheet.Cells.Item($row, $col).Value2, чтобы более точно определять, куда поместить данные при экспорте в Excel.

Что-то вроде

$row = 1
Get-Content $file | Foreach-Object {
   $cols = $_.split("`t")
   for ($i = 0; $i < $cols.count; $i++)
   {
      $Workbook.ActiveSheet.Cells.Item($row, $i+1).Value2 = $cols[$i]
   }
   $row++
}

Предупреждение: сухая кодировка! Вам, вероятно, понадобится немного try..catch.

2 голосов
/ 28 апреля 2011

Попробуйте Export-Xls , это выглядит очень красиво. Никогда не было возможности его использовать, но (виртуально) зная человека, который над ним работал, я уверен, что вы будете очень рады его использовать. Если вы пойдете с ним, пожалуйста, предоставьте отзыв, здесь будет оценено.


ВОЗМОЖНАЯ РЕШЕНИЕ ДЛЯ НЕПРАВИЛЬНЫХ СВОЙСТВ В Export-Xls

Функция Add-Array2Clipboard может быть изменена таким образом, чтобы она принимала новый входной параметр: массив, предоставляющий имя свойств, упорядоченных по мере необходимости.

Затем вы можете изменить раздел, где используется get-member. Глупый пример:

"z", "a", "c" | %{ get-member -name $_ -inputobject $thecurrentobject }

Это всего лишь пример того, как вы можете получить упорядоченные свойства из get-member.

0 голосов
/ 03 мая 2011

Я использовал модифицированную функцию Export-Xls , немного отличающуюся от предложенной пользователем empo. Это мой зов к этому

Export-Xls  $filtered -Path $outfile -WorksheetName "$wn" -SheetPosition "end"  | Out-Null #  -SheetPosition "end";

Однако текущая версия Export-Xls переупорядочивает столбцы представления в памяти файла csv-text -file. Я хочу, чтобы столбцы данных текстового файла были в их первоначальном порядке, поэтому мне пришлось взломать и упростить исходный код следующим образом:

    function Add-Array2Clipboard {
        param (
            [PSObject[]]$ConvertObject,
            [switch]$Header
        )
        process{
            $array = @();
            $line =""
            if ($Header) {

                $line = @()
                $row = $ConvertObject | Select -First 1
                $row.psobject.properties | Foreach {$line += "$($_.Name)" }
                $array += [String]::Join("`t", $line)


            }
            else {
                foreach($row in $ConvertObject){
                    $line =""
                    $vals = @()
                    $row.psobject.properties | Foreach {$vals +=  $_.Value}                      
                    $array += [String]::Join("`t", $vals)

                }

            }
            $array | clip.exe; 
        }

    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...