【问题标题】:Powershell set starting position for read dataPowershell设置读取数据的起始位置
【发布时间】:2020-05-16 22:25:13
【问题描述】:

伙计们,我是 Poweshell 脚本的新手,我一直在谷歌上搜索很多代码以获取 sn-ps 代码并了解它的作用并根据我的需要对其进行自定义。我正在做的一个小项目需要帮助。我有一个 EXCEL 电子表格,里面只有一个工作表。我从第 3 方 URL 下载了 excel,在 excel 工作表中我有数据。在 Excel 的顶部有几个单元格,我想忽略它们并从实际上有一个带有标题的表格的行开始。有了我所拥有的,我硬编码了起始位置的值,然后我通过使用 for 循环逐行读取将这些值写入 PIPE 分隔的文本文件。现在我想根据该特定行的列中的字符串动态获取该标题字段,然后开始从该位置读取直到文件末尾。

源数据看起来像这样。

源数据:

我有这样的代码。如您所见,我对列进行了硬编码,然后将数据写入我在顶部创建的文本文件中。我想根据标题字符串使起始位置动态,它可能出现在任何位置(在这种情况下它恰好是 11)。

#Download the Medicare Fee Scheule for the state website for the respective year

$url "https://med.noridianmedicare.com/documents/10525/23843395/California%2C%20Area+05%2C%202020+Medicare+Part+B+Fee+Schedule+Excel+File"
$path = "\\srqsctfs01\sftp\BA\MedicareFeeSchedule"
$archivepath = "\\srqsctfs01\sftp\BA\MedicareFeeSchedule\Archive" # Setting the Archive File path variable to moving the excel file to archive location
$file = "MedicareFeeSchedule2020_SFCounty" # Set a file name variable
$filename = $file + ".xlsx"
$outputfilepath = $path + "\" + $filename #Declare the Output filepath variable
$archivefilepath = $archivepath + "\" + $filename   #"# dummy comment to fix syntax highlighting in SO
$start_time = Get-Date
$wc = New-Object System.Net.WebClient
$wc.DownloadFile($url, $outputfilepath)
#OR
(New-Object System.Net.WebClient).DownloadFile($url, $outputfilepath)
Write-Output "Time taken: $((Get-Date).Subtract($start_time).Seconds) second(s)"
#Declare the file path and sheet name
$sheetName = "California, Area 05"

# CREATE AN EMPTY TEXT FILE ONLY IF IT DOES NOT ALREADY EXIST

$FileName = "MedicareFeeSchedule2020_SFCounty" + "_" + (Get-Date).tostring("MM-dd-yyyy")
$TextFilePath = $path + "\" + $FileName + ".txt"    #"# dummy comment to fix syntax highlighting in SO
if (!(Test-Path $TextFilePath))
{
New-Item -itemType File -Path $path -Name ($FileName + ".txt")
}
else
{
    Remove-Item $TextFilePath
}
#Create an instance of Excel.Application and Open Excel file
$objExcel = New-Object -ComObject Excel.Application
$workbook = $objExcel.Workbooks.Open($outputfilepath)
$sheet = $workbook.Worksheets.Item($sheetName)
$objExcel.Visible=$false
#Count max row
$rowMax = ($sheet.UsedRange.Rows).count
#Declare the starting positions
$rowNote,$colNote = 11,1
$rowProcedureCode,$colProcedureCode = 11,2
$rowModifier,$colModifier = 11,3
$rowParAmount,$colParAmount = 11,4
$rowNonParAmount,$colNonParAmount = 11,5
$rowLimitingChargeAmount,$colLimitingChargeAmount = 11,6
#loop to get values and store it
for ($i=1; $i -le $rowMax-1; $i++)
{
    $Note = $sheet.Cells.Item($rowNote+$i,$colNote).text
    $ProcedureCode = $sheet.Cells.Item($rowProcedureCode+$i,$colProcedureCode).text
    $Modifier = $sheet.Cells.Item($rowModifier+$i,$colModifier).text
    $ParAmount = $sheet.Cells.Item($rowParAmount+$i,$colParAmount).text
    $NonParAmount = $sheet.Cells.Item($rowNonParAmount+$i,$colNonParAmount).text
    $LimitingChargeAmount = $sheet.Cells.Item($rowLimitingChargeAmount+$i,$colLimitingChargeAmount).text
    $string = ($Note + "|"  + $ProcedureCode + "|" + $Modifier + "|" + $ParAmount + "|" + $NonParAmount + "|" + $LimitingChargeAmount)
    $string | Out-File -FilePath $TextFilePath -Append
}

#close excel file

$objExcel.quit()

非常感谢您为实现这一目标提供的任何帮助。

谢谢! 帕布

【问题讨论】:

    标签: regex excel powershell foreach


    【解决方案1】:

    我将通过捕获具有所需属性的对象中的值来简化此操作,然后将其写为管道分隔的 csv 文件,如下所示:

    # Create an instance of Excel.Application and Open Excel file
    $objExcel = New-Object -ComObject Excel.Application
    $workbook = $objExcel.Workbooks.Open($outputfilepath)
    $sheet = $workbook.Worksheets.Item($sheetName)
    $objExcel.Visible=$false
    # Count max row
    $rowMax = ($sheet.UsedRange.Rows).count
    # determine the row number where the table data starts
    $rowFirst = 11
    $colFirst = 1
    
    # loop to get values and store it
    $result = for ($i = $rowFirst; $i -le $rowMax; $i++) {
        [PsCustomObject]@{
            Note                 = $sheet.Cells.Item($i, $colFirst).text                       # or perhaps use .Value2 instead of .Text
            ProcedureCode        = $sheet.Cells.Item($i, $colFirst + 1).text
            Modifier             = $sheet.Cells.Item($i, $colFirst + 2).text
            ParAmount            = $sheet.Cells.Item($i, $colFirst + 3).text
            NonParAmount         = $sheet.Cells.Item($i, $colFirst + 4).text
            LimitingChargeAmount = $sheet.Cells.Item($i, $colFirst + 5).text
    
        }
    }
    
    # close excel file
    $objExcel.Quit()
    
    # IMPORTANT: remove the COM objects
    $null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($sheet)
    $null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($workbook)
    $null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($objExcel)
    [System.GC]::Collect()
    [System.GC]::WaitForPendingFinalizers()
    
    # show on screen
    $result | ConvertTo-Csv -Delimiter '|'
    
    # output to pipe delimited CSV file
    $result | Export-Csv -Path 'D:\TheTable.csv' -Delimiter '|' -NoTypeInformation
    

    一个 Csv 文件当然有一个标题和值的引号。 如果你坚持输出一个没有标题和没有引号的管道分隔文本文件,你可以像上面那样做,但是为了输出使用:

    $result | ForEach-Object { $_.PsObject.Properties.Value -join '|' }
    

    然后归档是:

    $result | ForEach-Object { $_.PsObject.Properties.Value -join '|' } | Out-File -FilePath $TextFilePath
    

    【讨论】:

    • 嗨 Theo,非常感谢您提供更好的优雅解决方案。如果我需要 PIPE 分隔文件中的标题行,我将如何更改您的最后一条语句?我包含了我使用的代码以及与您合并的代码,因此任何需要它的人都可以将它用于他们的项目。
    • 我想我可以调整将 $k 值设置为起始位置变量的部分,这样就可以解决这个问题。谢谢 Theo!非常感谢
    【解决方案2】:
    $url = "https://med.noridianmedicare.com/documents/10525/23843395/California%2C%20Area+05%2C%202020+Medicare+Part+B+Fee+Schedule+Excel+File"
    $path = "\\srqsctfs01\sftp\BA\MedicareFeeSchedule"
    $archivepath = "\\srqsctfs01\sftp\BA\MedicareFeeSchedule\Archive" # Setting the Archive File path variable to moving the excel file to archive location
    $file = "MedicareFeeSchedule2020_SFCounty" # Set a file name variable
    $filename = $file + ".xlsx"
    $outputfilepath = $path + "\" + $filename  #Declare the Output filepath variable
    $archivefilepath = $archivepath + "\" + $filename
    $start_time = Get-Date
    $wc = New-Object System.Net.WebClient
    $wc.DownloadFile($url, $outputfilepath)
    #OR
    (New-Object System.Net.WebClient).DownloadFile($url, $outputfilepath)
    Write-Output "Time taken: $((Get-Date).Subtract($start_time).Seconds) second(s)"
    
    # CREATE AN EMPTY TEXT FILE ONLY IF IT DOES NOT ALREADY EXIST
    $FileName = "MedicareFeeSchedule2020_SFCounty" + "_" + (Get-Date).tostring("MM-dd-yyyy")
    $TextFilePath = $path + "\" + $FileName + ".txt"
    if (!(Test-Path $TextFilePath))
    {
    New-Item -itemType File -Path $path -Name ($FileName + ".txt")
    }
    else
    {
        Remove-Item $TextFilePath
    }
    
    # Create an instance of Excel.Application and Open Excel file
    $objExcel = New-Object -ComObject Excel.Application
    $workbook = $objExcel.Workbooks.Open($outputfilepath)
    $sheet = $workbook.Worksheets.Item($sheetName)
    $objExcel.Visible=$false
    
    # Count max row
    $rowMax = ($sheet.UsedRange.Rows).count
    $colMax = ($sheet.UsedRange.Columns).count
    
    # Loop through each row
    
    for ($i=1; $i -le $rowMax; $i++)
    
    {
    
        $row_str = ""
        for ($j=1; $j -le $colMax; $j++)
        {
            $row_str = $row_str + $sheet.Cells.Item($i,$j).text + "|"
            if ($row_str -like 'Note|Procedure Code|Modifier|Par Amount|Non-Par Amount|Limiting Charge Amount|')
            {
                $startposition = $i
            }
            break # BREAK OUT OF INNER FOR LOOP
        }
            $k = $startposition + 1
        break # BREAK OUT OF OUTER FOR LOOP
    
    }
    # determine the row number where the table data starts
    $rowFirst = $k
    $colFirst = 1
    
    # loop to get values and store it
    $result = for ($i = $rowFirst; $i -le $rowMax; $i++) {
        [PsCustomObject]@{
            Note                 = $sheet.Cells.Item($i, $colFirst).text                       # or perhaps use .Value2 instead of .Text
            ProcedureCode        = $sheet.Cells.Item($i, $colFirst + 1).text
            Modifier             = $sheet.Cells.Item($i, $colFirst + 2).text
            ParAmount            = $sheet.Cells.Item($i, $colFirst + 3).text
            NonParAmount         = $sheet.Cells.Item($i, $colFirst + 4).text
            LimitingChargeAmount = $sheet.Cells.Item($i, $colFirst + 5).text
    
        }
    }
    
    # close excel file
    $objExcel.Quit()
    
    # IMPORTANT: remove the COM objects
    $null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($sheet)
    $null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($workbook)
    $null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($objExcel)
    [System.GC]::Collect()
    [System.GC]::WaitForPendingFinalizers()
    
    # writing output to a text file
    $result | ForEach-Object { $_.PsObject.Properties.Value -join '|' } | Out-File -FilePath $TextFilePath
    

    【讨论】:

      猜你喜欢
      • 2014-07-29
      • 1970-01-01
      • 1970-01-01
      • 2013-01-20
      • 1970-01-01
      • 1970-01-01
      • 2012-11-16
      • 2011-07-08
      • 2021-04-30
      相关资源
      最近更新 更多