Nebelz Cheez
Nebelz Cheez

Reputation: 307

Search for multiple items in excel and return the entire feild

I have an excel file with multiple sheets which are populated with sku and quantity column. I need to search the entire workbook for multiple items and return their quantity. products.txt contains the sku IDs.

ABC1234
BCDH214
LDJI983

And the Excel workbook, inventory.xlsx contains the following columns

**sku**                  ***Quantity***
ABC1234                        2
BCDH214                        0     
LDJI983                        1 

I would like to run prodcuts.txt against inventory.xlsx and return the quantity of each product.

Can this be done via powershell? or any other way to run this kind of query?

Upvotes: 1

Views: 646

Answers (1)

Kory Gill
Kory Gill

Reputation: 7163

Use the code shown here Get Excel data without Excel and ensure you have the ACE.OLEDB provider installed.

I created a simple xlsx with:

SKU    Quantity
one    1
two    4
three  9

Then I called into Excel:

$path = 'd:\test\exceldb.xlsx'
$results = Get-ExcelData -Path $path -Query 'SELECT * FROM [Sheet1$]'

$stuffFromProductsTxtFile = 'one', 'two', 'three'

foreach ($sku in $stuffFromProductsTxtFile)
{
    $results.Rows | Where-Object {$_.SKU -eq $sku} | % {Write-Output "$($_.SKU) has quantity $($_.Quantity)"}
}

This gives the following output:

one has quantity 1
two has quantity 4
three has quantity 9

I think with this, you can change accordingly to whatever you require.

For completeness, I have copied the sample code from the aforementioned MSDN blog here:

function Get-ExcelData {
    [CmdletBinding(DefaultParameterSetName='Worksheet')]
    Param(
        [Parameter(Mandatory=$true, Position=0)]
        [String] $Path,

        [Parameter(Position=1, ParameterSetName='Worksheet')]
        [String] $WorksheetName = 'Sheet1',

        [Parameter(Position=1, ParameterSetName='Query')]
        [String] $Query = 'SELECT * FROM [Sheet1$]'
    )

    switch ($pscmdlet.ParameterSetName) {
        'Worksheet' {
            $Query = 'SELECT * FROM [{0}$]' -f $WorksheetName
            break
        }
        'Query' {
            # Make sure the query is in the correct syntax (e.g. 'SELECT * FROM [SheetName$]')
            $Pattern = '.*from\b\s*(?<Table>\w+).*'
            if($Query -match $Pattern) {
                $Query = $Query -replace $Matches.Table, ('[{0}$]' -f $Matches.Table)
            }
        }
    }

    # Create the scriptblock to run in a job
    $JobCode = {
        Param($Path, $Query)

        # Check if the file is XLS or XLSX 
        if ((Get-Item -Path $Path).Extension -eq 'xls') {
            $Provider = 'Microsoft.Jet.OLEDB.4.0'
            $ExtendedProperties = 'Excel 8.0;HDR=YES;IMEX=1'
        } else {
            $Provider = 'Microsoft.ACE.OLEDB.12.0'
            $ExtendedProperties = 'Excel 12.0;HDR=YES'
        }

        # Build the connection string and connection object
        $ConnectionString = 'Provider={0};Data Source={1};Extended Properties="{2}"' -f $Provider, $Path, $ExtendedProperties
        $Connection = New-Object System.Data.OleDb.OleDbConnection $ConnectionString

        try {
            # Open the connection to the file, and fill the datatable
            $Connection.Open()
            $Adapter = New-Object -TypeName System.Data.OleDb.OleDbDataAdapter $Query, $Connection
            $DataTable = New-Object System.Data.DataTable
            $Adapter.Fill($DataTable) | Out-Null
        }
        catch {
            # something went wrong :-(
            Write-Error $_.Exception.Message
        }
        finally {
            # Close the connection
            if ($Connection.State -eq 'Open') {
                $Connection.Close()
            }
        }

        # Return the results as an array
        return ,$DataTable
    }

    # Run the code in a 32bit job, since the provider is 32bit only
    $job = Start-Job $JobCode -RunAs32 -ArgumentList $Path, $Query
    $job | Wait-Job | Receive-Job
    Remove-Job $job
}

Upvotes: 1

Related Questions