@@ -1,25 +1,25 @@
Function Merge-Worksheet {
Function Merge-Worksheet {
<#
<#
. Synopsis
. Synopsis
Merges two w orksheets (or other objects) into a single w orksheet with differences marked up .
Merges two W orksheets (or other objects) into a single W orksheet with differences marked up .
. Description
. Description
The Compare-Worksheet command takes two w orksheets and marks differences in the source document, and optionally outputs a grid showing the changes .
The Compare-Worksheet command takes two W orksheets and marks differences in the source document, and optionally outputs a grid showing the changes .
By contrast the Merge-Worksheet command takes the w orksheets and combines them into a single sheet showing the old and new data side by side .
By contrast the Merge-Worksheet command takes the W orksheets and combines them into a single sheet showing the old and new data side by side .
Although it is designed to work with Excel data it can work with arrays of any kind of object; so it can be a merge *of* w orksheets, or a merge *to* w orksheet .
Although it is designed to work with Excel data it can work with arrays of any kind of object; so it can be a merge *of* W orksheets, or a merge *to* W orksheet .
. Example
. Example
merge-w orksheet "Server54 . xlsx" "Server55 . xlsx" -WorkS heetName services -OutputFile Services . xlsx -OutputSheetName 54-55 -show
merge-W orksheet "Server54 . xlsx" "Server55 . xlsx" -Works heetName services -OutputFile Services . xlsx -OutputSheetName 54-55 -show
The workbooks contain audit information for two servers, one page contains a list of services . This command creates a w orksheet named 54-55
The workbooks contain audit information for two servers, one page contains a list of services . This command creates a W orksheet named 54-55
in a workbook named services which shows all the services and their differences, and opens it in Excel .
in a workbook named services which shows all the services and their differences, and opens it in Excel .
. Example
. Example
merge-w orksheet "Server54 . xlsx" "Server55 . xlsx" -WorkS heetName services -OutputFile Services . xlsx -OutputSheetName 54-55 -HideEqual -AddBackgroundColor LightBlue -show
merge-W orksheet "Server54 . xlsx" "Server55 . xlsx" -Works heetName services -OutputFile Services . xlsx -OutputSheetName 54-55 -HideEqual -AddBackgroundColor LightBlue -show
This modifies the previous command to hide the equal rows in the output sheet and changes the color used to mark rows added to the second file .
This modifies the previous command to hide the equal rows in the output sheet and changes the color used to mark rows added to the second file .
. Example
. Example
merge-w orksheet -OutputFile . \j1 . xlsx -OutputSheetName test11 -ReferenceObject (dir . \ImportExcel\4 . 0 . 7) -DifferenceObject (dir . \ImportExcel\4 . 0 . 8) -Property Length -Show
merge-W orksheet -OutputFile . \j1 . xlsx -OutputSheetName test11 -ReferenceObject (dir . \ImportExcel\4 . 0 . 7) -DifferenceObject (dir . \ImportExcel\4 . 0 . 8) -Property Length -Show
This version compares two directories, and marks what has changed .
This version compares two directories, and marks what has changed .
Because no "Key" property is given, "Name" is assumed to be the key and the only other property examined is length .
Because no "Key" property is given, "Name" is assumed to be the key and the only other property examined is length .
Files which are added or deleted or have changed size will be highlighed in the output sheet . Changes to dates or other attributes will be ignored .
Files which are added or deleted or have changed size will be highlighed in the output sheet . Changes to dates or other attributes will be ignored .
. Example
. Example
merge-w orksheet -RefO (dir . \ImportExcel\4 . 0 . 7) -DiffO (dir . \ImportExcel\4 . 0 . 8) -Pr Length | Out-GridView
merge-W orksheet -RefO (dir . \ImportExcel\4 . 0 . 7) -DiffO (dir . \ImportExcel\4 . 0 . 8) -Pr Length | Out-GridView
This time no file is written and the results -which include all properties, not just length, are output and sent to Out-Gridview .
This time no file is written and the results -which include all properties, not just length, are output and sent to Out-Gridview .
This version uses aliases to shorten the parameters,
This version uses aliases to shorten the parameters,
(OutputFileName can be "outFile" and the sheet "OutSheet" : DifferenceObject & ReferenceObject can be DiffObject & RefObject) .
(OutputFileName can be "outFile" and the sheet "OutSheet" : DifferenceObject & ReferenceObject can be DiffObject & RefObject) .
@@ -27,58 +27,70 @@
[ cmdletbinding ( SupportsShouldProcess = $true ) ]
[ cmdletbinding ( SupportsShouldProcess = $true ) ]
Param (
Param (
#First Excel file to compare. You can compare two Excel files or two other objects but not one of each.
#First Excel file to compare. You can compare two Excel files or two other objects but not one of each.
[ parameter ( ParameterSetName = 'A' , Mandatory = $true , Position = 0 ) ]
[ parameter ( ParameterSetName = 'A' , Mandatory = $true , Position = 0 ) ] #A = Compare two files default headers
[ parameter ( ParameterSetName = 'B' , Mandatory = $true , Position = 0 ) ]
[ parameter ( ParameterSetName = 'B' , Mandatory = $true , Position = 0 ) ] #B = Compare two files user supplied headers
[ parameter ( ParameterSetName = 'C' , Mandatory = $true , Position = 0 ) ]
[ parameter ( ParameterSetName = 'C' , Mandatory = $true , Position = 0 ) ] #C = Compare two files headers P1, P2, P3 etc
$Referencefile ,
$Referencefile ,
#Second Excel file to compare.
#Second Excel file to compare.
[ parameter ( ParameterSetName = 'A' , Mandatory = $true , Position = 1 ) ]
[ parameter ( ParameterSetName = 'A' , Mandatory = $true , Position = 1 ) ]
[ parameter ( ParameterSetName = 'B' , Mandatory = $true , Position = 1 ) ]
[ parameter ( ParameterSetName = 'B' , Mandatory = $true , Position = 1 ) ]
[ parameter ( ParameterSetName = 'C' , Mandatory = $true , Position = 1 ) ]
[ parameter ( ParameterSetName = 'C' , Mandatory = $true , Position = 1 ) ]
[ parameter ( ParameterSetName = 'E' , Mandatory = $true , Position = 1 ) ]
[ parameter ( ParameterSetName = 'E' , Mandatory = $true , Position = 1 ) ] #D Compat two objects; E = Compare one object one file that uses default headers
[ parameter ( ParameterSetName = 'F' , Mandatory = $true , Position = 1 ) ] #F = Compare one object one file that uses user supplied headers
[ parameter ( ParameterSetName = 'G' , Mandatory = $true , Position = 1 ) ] #G Compare one object one file that uses headers P1, P2, P3 etc
$Differencefile ,
$Differencefile ,
#Name(s) of w orksheets to compare,
#Name(s) of W orksheets to compare,
[ parameter ( ParameterSetName = 'A' , Position = 2 ) ]
[ parameter ( ParameterSetName = 'A' , Position = 2 ) ] #Applies to all sets EXCEPT D which is two objects (no sheets)
[ parameter ( ParameterSetName = 'B' , Position = 2 ) ]
[ parameter ( ParameterSetName = 'B' , Position = 2 ) ]
[ parameter ( ParameterSetName = 'C' , Position = 2 ) ]
[ parameter ( ParameterSetName = 'C' , Position = 2 ) ]
[ parameter ( ParameterSetName = 'E' , Position = 2 ) ]
[ parameter ( ParameterSetName = 'E' , Position = 2 ) ]
$WorkSheetName = " Sheet1 " ,
[ parameter ( ParameterSetName = 'F' , Position = 2 ) ]
[ parameter ( ParameterSetName = 'G' , Position = 2 ) ]
$WorksheetName = " Sheet1 " ,
#The row from where we start to import data, all rows above the StartRow are disregarded. By default this is the first row.
#The row from where we start to import data, all rows above the StartRow are disregarded. By default this is the first row.
[ parameter ( ParameterSetName = 'A' ) ]
[ parameter ( ParameterSetName = 'A' ) ] #Applies to all sets EXCEPT D which is two objects (no sheets, so no start row )
[ parameter ( ParameterSetName = 'B' ) ]
[ parameter ( ParameterSetName = 'B' ) ]
[ parameter ( ParameterSetName = 'C' ) ]
[ parameter ( ParameterSetName = 'C' ) ]
[ parameter ( ParameterSetName = 'E' ) ]
[ parameter ( ParameterSetName = 'E' ) ]
[ parameter ( ParameterSetName = 'F' ) ]
[ parameter ( ParameterSetName = 'G' ) ]
[ int ] $Startrow = 1 ,
[ int ] $Startrow = 1 ,
#Specifies custom property names to use, instead of the values defined in the column headers of the TopRow.
#Specifies custom property names to use, instead of the values defined in the column headers of the TopRow.
[ Parameter ( ParameterSetName = 'B' , Mandatory = $true ) ]
[ Parameter ( ParameterSetName = 'B' , Mandatory = $true ) ] #Compare object + sheet or 2 sheets with user supplied headers
[ Parameter ( ParameterSetName = 'F' , Mandatory = $true ) ]
[ String[] ] $Headername ,
[ String[] ] $Headername ,
#Automatically generate property names (P1, P2, P3, ..) instead of the using the values the top row of the sheet.
#Automatically generate property names (P1, P2, P3, ..) instead of the using the values the top row of the sheet.
[ Parameter ( ParameterSetName = 'C' , Mandatory = $true ) ]
[ Parameter ( ParameterSetName = 'C' , Mandatory = $true ) ] #Compare object + sheet or 2 sheets with headers of P1, P2, P3 ...
[ Parameter ( ParameterSetName = 'G' , Mandatory = $true ) ]
[ switch ] $NoHeader ,
[ switch ] $NoHeader ,
#O bject to compare if a w orksheet is NOT being used.
#Reference o bject to compare if a W orksheet is NOT being used. Reference object can combine with a difference sheet or difference object
[ parameter ( ParameterSetName = 'D' , Mandatory = $true ) ]
[ parameter ( ParameterSetName = 'D' , Mandatory = $true ) ]
[ parameter ( ParameterSetName = 'E' , Mandatory = $true ) ]
[ parameter ( ParameterSetName = 'E' , Mandatory = $true ) ]
[ parameter ( ParameterSetName = 'F' , Mandatory = $true ) ]
[ parameter ( ParameterSetName = 'G' , Mandatory = $true ) ]
[ Alias ( 'RefObject' ) ]
[ Alias ( 'RefObject' ) ]
$ReferenceObject ,
$ReferenceObject ,
#O bject to compare if a w orksheet is NOT being used.
#Difference o bject to compare if a W orksheet is NOT being used for either half. Can't have a reference sheet and difference object .
[ parameter ( ParameterSetName = 'D' , Mandatory = $true , Position = 1 ) ]
[ parameter ( ParameterSetName = 'D' , Mandatory = $true , Position = 1 ) ]
[ Alias ( 'DiffObject' ) ]
[ Alias ( 'DiffObject' ) ]
$DifferenceObject ,
$DifferenceObject ,
[ parameter ( ParameterSetName = 'D' , Position = 2 ) ]
[ parameter ( ParameterSetName = 'D' , Position = 2 ) ]
[ parameter ( ParameterSetName = 'E' , Position = 3 ) ]
[ parameter ( ParameterSetName = 'E' , Position = 2 ) ]
[ parameter ( ParameterSetName = 'F' , Position = 2 ) ]
[ parameter ( ParameterSetName = 'G' , Position = 2 ) ]
#If there isn't a filename to use to label data from the "Difference" side, DiffPrefix is used, it defaults to "=>"
#If there isn't a filename to use to label data from the "Difference" side, DiffPrefix is used, it defaults to "=>"
$DiffPrefix = " => " ,
$DiffPrefix = " => " ,
#File to hold merged data.
#File to hold merged data.
[ parameter ( Position = 3 ) ]
[ parameter ( Position = 3 ) ]
[ Alias ( 'OutFile' ) ]
[ Alias ( 'OutFile' ) ]
$OutputFile ,
$OutputFile ,
#Name of w orksheet to output - if none specified will use the reference w orksheet name.
#Name of W orksheet to output - if none specified will use the reference W orksheet name.
[ parameter ( Position = 4 ) ]
[ parameter ( Position = 4 ) ]
[ Alias ( 'OutSheet' ) ]
[ Alias ( 'OutSheet' ) ]
$OutputSheetName = " Sheet1 " ,
$OutputSheetName = " Sheet1 " ,
@@ -105,35 +117,36 @@
)
)
#region Read Excel data
#region Read Excel data
if ( $Referencefile -and $Differencefile ) {
if ( $Referencefile -and $Differencefile ) {
#if the filenames don't resolve, give up now.
#if the filenames don't resolve, give up now.
try { $oneFile = ( ( Resolve-Path -Path $Referencefile -ErrorAction Stop ) . path -eq ( Resolve-Path -Path $Differencefile -ErrorAction Stop ) . path ) }
try { $oneFile = ( ( Resolve-Path -Path $Referencefile -ErrorAction Stop ) . path -eq ( Resolve-Path -Path $Differencefile -ErrorAction Stop ) . path ) }
Catch { Write-Warning -Message " Could not Resolve the filenames. " ; return }
Catch { Write-Warning -Message " Could not Resolve the filenames. " ; return }
#If we have one file , we must have two different w orksheet names. If we have two files $w orksheetName can be a single string or two strings.
#If we have one file , we must have two different W orksheet names. If we have two files $W orksheetName can be a single string or two strings.
if ( $onefile -and ( ( $WorkS heetName . count -ne 2 ) -or $WorkS heetName [ 0 ] -eq $WorkS heetName [ 1 ] ) ) {
if ( $onefile -and ( ( $Works heetName . count -ne 2 ) -or $Works heetName [ 0 ] -eq $Works heetName [ 1 ] ) ) {
Write-Warning -Message " If both the Reference and difference file are the same then w orksheet name must provide 2 different names "
Write-Warning -Message " If both the Reference and difference file are the same then W orksheet name must provide 2 different names "
return
return
}
}
if ( $WorkS heetName . count -eq 2 ) { $w orkS heet2 = $DiffPrefix = $WorkS heetName [ 1 ] ; $w orksheet1 = $WorkS heetName [ 0 ] ; }
if ( $Works heetName . count -eq 2 ) { $W orks heet2 = $DiffPrefix = $Works heetName [ 1 ] ; $W orksheet1 = $Works heetName [ 0 ] ; }
elseif ( $WorkS heetName -is [ string ] ) { $w orksheet2 = $w orkS heet1 = $WorkS heetName ;
elseif ( $Works heetName -is [ string ] ) { $W orksheet2 = $W orks heet1 = $Works heetName ;
$DiffPrefix = ( Split-Path -Path $Differencefile -Leaf ) -replace " \.xlsx $ " , " " }
$DiffPrefix = ( Split-Path -Path $Differencefile -Leaf ) -replace " \.xlsx $ " , " " }
else { Write-Warning -Message " You must provide either a single w orksheet name or two names. " ; return }
else { Write-Warning -Message " You must provide either a single W orksheet name or two names. " ; return }
$params = @ { ErrorAction = [ System.Management.Automation.ActionPreference ] :: Stop }
$params = @ { ErrorAction = [ System.Management.Automation.ActionPreference ] :: Stop }
foreach ( $p in @ ( " HeaderName " , " NoHeader " , " StartRow " ) ) { if ( $PSBoundParameters [ $p ] ) { $params [ $p ] = $PSBoundParameters [ $p ] } }
foreach ( $p in @ ( " HeaderName " , " NoHeader " , " StartRow " ) ) { if ( $PSBoundParameters [ $p ] ) { $params [ $p ] = $PSBoundParameters [ $p ] } }
try {
try {
$ReferenceObject = Import-Excel -Path $Referencefile -WorksheetName $WorkS heet1 @params
$ReferenceObject = Import-Excel -Path $Referencefile -WorksheetName $Works heet1 @params
$DifferenceObject = Import-Excel -Path $Differencefile -WorksheetName $WorkS heet2 @Params
$DifferenceObject = Import-Excel -Path $Differencefile -WorksheetName $Works heet2 @Params
}
}
Catch { Write-Warning -Message " Could not read the w orksheet from $Referencefile :: $w orksheet1 and/or $Differencefile :: $w orksheet2 . " ; return }
Catch { Write-Warning -Message " Could not read the W orksheet from $Referencefile :: $W orksheet1 and/or $Differencefile :: $W orksheet2 . " ; return }
if ( $NoHeader ) { $firstDataRow = $Startrow } else { $firstDataRow = $Startrow + 1 }
if ( $NoHeader ) { $firstDataRow = $Startrow } else { $firstDataRow = $Startrow + 1 }
}
}
elseif ( $Differencefile ) {
elseif ( $Differencefile ) {
if ( $WorkS heetName -isnot [ string ] ) { Write-Warning -Message " You must provide a single w orksheet name. " ; return }
if ( $Works heetName -isnot [ string ] ) { Write-Warning -Message " You must provide a single W orksheet name. " ; return }
$params = @ { WorkS heetName = $WorkS heetName ; Path = $Differencefile ; ErrorAction = [ System.Management.Automation.ActionPreference ] :: Stop ; }
$params = @ { Works heetName = $Works heetName ; Path = $Differencefile ; ErrorAction = [ System.Management.Automation.ActionPreference ] :: Stop }
foreach ( $p in @ ( " HeaderName " , " NoHeader " , " StartRow " ) ) { if ( $PSBoundParameters [ $p ] ) { $params [ $p ] = $PSBoundParameters [ $p ] } }
try { $DifferenceObject = Import-Excel @Params }
try { $DifferenceObject = Import-Excel @Params }
Catch { Write-Warning -Message " Could not read the w orksheet ' $WorkS heetName ' from $Differencefile :: $WorkS heetName . " ; return }
Catch { Write-Warning -Message " Could not read the W orksheet ' $Works heetName ' from $Differencefile :: $Works heetName . " ; return }
if ( $DiffPrefix -eq " => " ) {
if ( $DiffPrefix -eq " => " ) {
$DiffPrefix = ( Split-Path -Path $Differencefile -Leaf ) -replace " \.xlsx $ " , " "
$DiffPrefix = ( Split-Path -Path $Differencefile -Leaf ) -replace " \.xlsx $ " , " "
}
}
@@ -149,7 +162,7 @@
$headings = $DifferenceObject [ 0 ] . psobject . Properties . Name # This preserves the sequence - using get-member would sort them alphabetically! There may be extra properties in
$headings = $DifferenceObject [ 0 ] . psobject . Properties . Name # This preserves the sequence - using get-member would sort them alphabetically! There may be extra properties in
if ( $NoHeader -and " Name " -eq $Key ) { $Key = " p1 " }
if ( $NoHeader -and " Name " -eq $Key ) { $Key = " p1 " }
if ( $headings -notcontains $Key -and
if ( $headings -notcontains $Key -and
( '*' -ne $Key ) ) { Write-Warning -Message " You need to specify one of the headings in the sheet ' $w orksheet1 ' as a key. " ; return }
( '*' -ne $Key ) ) { Write-Warning -Message " You need to specify one of the headings in the sheet ' $W orksheet1 ' as a key. " ; return }
foreach ( $p in $Property ) { $propList + = ( $headings . where ( { $_ -like $p } ) ) }
foreach ( $p in $Property ) { $propList + = ( $headings . where ( { $_ -like $p } ) ) }
foreach ( $p in $ExcludeProperty ) { $propList = $propList . where ( { $_ -notlike $p } ) }
foreach ( $p in $ExcludeProperty ) { $propList = $propList . where ( { $_ -notlike $p } ) }
if ( ( $propList -notcontains $Key ) -and
if ( ( $propList -notcontains $Key ) -and
@@ -199,19 +212,29 @@
else { $Rowhash [ $row . $key ] = $rowNo }
else { $Rowhash [ $row . $key ] = $rowNo }
$rowNo + +
$rowNo + +
}
}
if ( $DifferenceObject . count -gt $Rowhash . Keys . Count ) {
Write-Warning -Message " Difference object has $( $DifferenceObject . Count ) rows; but only $( $Rowhash . keys . count ) unique keys "
}
if ( $Key -eq '*' ) { $key = " _ALL " }
if ( $Key -eq '*' ) { $key = " _ALL " }
#endregion
#endregion
#We need to know all the properties we've met on the objects we've diffed
$eDiffProps = [ ordered ] @ { }
#When we do a compare object changes will result in two rows so we group them and join them together.
$expandedDiff = Compare-Object -ReferenceObject $ReferenceObject -DifferenceObject $DifferenceObject -Property $propList -PassThru -IncludeEqual |
$expandedDiff = Compare-Object -ReferenceObject $ReferenceObject -DifferenceObject $DifferenceObject -Property $propList -PassThru -IncludeEqual |
Group-Object -Property $key | ForEach-Object {
Group-Object -Property $key | ForEach-Object {
#The value of the key column is the name of the g roup.
#The value of the key column is the name of the G roup.
$keyval = $_ . name
$keyval = $_ . name
#we're going to create a custom object from a hash table. ??Might no longer need to preserve the field order
#we're going to create a custom object from a hash table.
$hash = [ ordered ] @ { }
$hash = [ ordered ] @ { }
foreach ( $result in $_ . Group ) {
foreach ( $result in $_ . Group ) {
if ( $result . SideIndicator -ne " => " ) { $hash [ " _Row " ] = $result . _Row }
if ( $result . SideIndicator -ne " => " ) { $hash [ " _Row " ] = $result . _Row }
elseif ( -not $hash [ " $DiffPrefix Row " ] ) { $hash [ " _Row " ] = " " }
elseif ( -not $hash [ " $DiffPrefix Row " ] ) { $hash [ " _Row " ] = " " }
#if we have already set the side, be this must the second record, so set side to indicate "changed"
#if we have already set the side, this must be the second record, so set side to indicate "changed"; if we got two "Same" indicators we may have a classh of keys
if ( $hash . Side ) { $hash . Side = " <> " } else { $hash [ " Side " ] = $result . SideIndicator }
if ( $hash . Side ) {
if ( $hash . Side -eq $result . SideIndicator ) { Write-Warning -Message " ' $keyval ' may be a duplicate. " }
$hash . Side = " <> "
}
else { $hash [ " Side " ] = $result . SideIndicator }
switch ( $hash . side ) {
switch ( $hash . side ) {
'==' { $hash [ " $DiffPrefix is " ] = 'Same' }
'==' { $hash [ " $DiffPrefix is " ] = 'Same' }
'=>' { $hash [ " $DiffPrefix is " ] = 'Added' }
'=>' { $hash [ " $DiffPrefix is " ] = 'Added' }
@@ -224,7 +247,7 @@
}
}
'<=' { $hash [ " $DiffPrefix is " ] = 'Removed' }
'<=' { $hash [ " $DiffPrefix is " ] = 'Removed' }
}
}
#find the number of the row in the the "difference" object which has this key. If it is the object is only the reference this will be blank.
#find the number of the row in the the "difference" object which has this key. If it is the object is only in the reference this will be blank.
$hash [ " $DiffPrefix Row " ] = $Rowhash [ $keyval ]
$hash [ " $DiffPrefix Row " ] = $Rowhash [ $keyval ]
$hash [ $key ] = $keyval
$hash [ $key ] = $keyval
#Create FieldName and/or =>FieldName columns
#Create FieldName and/or =>FieldName columns
@@ -236,6 +259,8 @@
elseif ( $result . SideIndicator -eq " => " ) { $hash [ ( " $DiffPrefix $p " ) ] = $result . $P }
elseif ( $result . SideIndicator -eq " => " ) { $hash [ ( " $DiffPrefix $p " ) ] = $result . $P }
}
}
}
}
foreach ( $k in $hash . keys ) { $eDiffProps [ $k ] = $true }
[ Pscustomobject ] $hash
[ Pscustomobject ] $hash
} | Sort-Object -Property " _row "
} | Sort-Object -Property " _row "
@@ -246,35 +271,35 @@
$expandedDiff = $expandedDiff | Sort-Object -Property " $DiffPrefix Row "
$expandedDiff = $expandedDiff | Sort-Object -Property " $DiffPrefix Row "
for ( $i = 1 ; $i -lt $expandedDiff . Count ; $i + + ) { if ( -not $expandedDiff [ $i ] . " _Row " ) { $expandedDiff [ $i ] . " _Row " = $expandedDiff [ $i - 1 ] . " _Row " } }
for ( $i = 1 ; $i -lt $expandedDiff . Count ; $i + + ) { if ( -not $expandedDiff [ $i ] . " _Row " ) { $expandedDiff [ $i ] . " _Row " = $expandedDiff [ $i - 1 ] . " _Row " } }
$AllProps = @ ( " _Row " ) + $OutputProps + $expandedDiff [ 0 ] . psobject . propertie s . name . where ( { $_ -notin ( $outputProps + @ ( " _row " , " side " , " SideIndicator " , " _ALL " ) ) } )
$AllProps = @ ( " _Row " ) + $OutputProps + $eDiffProp s . keys . where ( { $_ -notin ( $outputProps + @ ( " _row " , " side " , " SideIndicator " , " _ALL " ) ) } )
if ( $PassThru -or -not $OutputFile ) { return ( $expandedDiff | Select-Object -Property $allprops | Sort-Object -Property " _row " , " $DiffPrefix Row " | Update-FirstObjectProperties ) }
if ( $PassThru -or -not $OutputFile ) { return ( $expandedDiff | Select-Object -Property $allprops | Sort-Object -Property " _row " , " $DiffPrefix Row " ) }
elseif ( $PSCmdlet . ShouldProcess ( $OutputFile , " Write Output to Excel file " ) ) {
elseif ( $PSCmdlet . ShouldProcess ( $OutputFile , " Write Output to Excel file " ) ) {
$expandedDiff = $expandedDiff | Sort-Object -Property " _row " , " $DiffPrefix Row "
$expandedDiff = $expandedDiff | Sort-Object -Property " _row " , " $DiffPrefix Row "
$xl = $expandedDiff | Select-Object -Property $OutputProps | Update-FirstObjectProperties |
$xl = $expandedDiff | Select-Object -Property $OutputProps | Update-FirstObjectProperties |
Export-Excel -Path $OutputFile -WorkS heetname $OutputSheetName -FreezeTopRow -BoldTopRow -AutoSize -AutoFilter -PassThru
Export-Excel -Path $OutputFile -Works heetname $OutputSheetName -FreezeTopRow -BoldTopRow -AutoSize -AutoFilter -PassThru
$ws = $xl . Workbook . Worksheets [ $OutputSheetName ]
$ws = $xl . Workbook . Worksheets [ $OutputSheetName ]
for ( $i = 0 ; $i -lt $expandedDiff . Count ; $i + + ) {
for ( $i = 0 ; $i -lt $expandedDiff . Count ; $i + + ) {
if ( $expandedDiff [ $i ] . side -ne " == " ) {
if ( $expandedDiff [ $i ] . side -ne " == " ) {
Set-ExcelRange -WorkS heet $ws -Range ( " A " + ( $i + 2 ) ) -FontColor $KeyFontColor
Set-ExcelRange -Works heet $ws -Range ( " A " + ( $i + 2 ) ) -FontColor $KeyFontColor
}
}
elseif ( $HideEqual ) { $ws . row ( $i + 2 ) . hidden = $true }
elseif ( $HideEqual ) { $ws . row ( $i + 2 ) . hidden = $true }
if ( $expandedDiff [ $i ] . side -eq " <> " ) {
if ( $expandedDiff [ $i ] . side -eq " <> " ) {
$range = $ws . Dimension -replace " \d+ " , ( $i + 2 )
$range = $ws . Dimension -replace " \d+ " , ( $i + 2 )
Set-ExcelRange -WorkS heet $ws -Range $range -BackgroundColor $ChangeBackgroundColor
Set-ExcelRange -Works heet $ws -Range $range -BackgroundColor $ChangeBackgroundColor
}
}
elseif ( $expandedDiff [ $i ] . side -eq " <= " ) {
elseif ( $expandedDiff [ $i ] . side -eq " <= " ) {
$rangeR1C1 = " R[{0}]C[1]:R[{0}]C[{1}] " -f ( $i + 2 ) , $lastRefColNo
$rangeR1C1 = " R[{0}]C[1]:R[{0}]C[{1}] " -f ( $i + 2 ) , $lastRefColNo
$range = [ OfficeOpenXml.ExcelAddress ] :: TranslateFromR1C1 ( $rangeR1C1 , 0 , 0 )
$range = [ OfficeOpenXml.ExcelAddress ] :: TranslateFromR1C1 ( $rangeR1C1 , 0 , 0 )
Set-ExcelRange -WorkS heet $ws -Range $range -BackgroundColor $DeleteBackgroundColor
Set-ExcelRange -Works heet $ws -Range $range -BackgroundColor $DeleteBackgroundColor
}
}
elseif ( $expandedDiff [ $i ] . side -eq " => " ) {
elseif ( $expandedDiff [ $i ] . side -eq " => " ) {
if ( $propList . count -gt 1 ) {
if ( $propList . count -gt 1 ) {
$rangeR1C1 = " R[{0}]C[{1}]:R[{0}]C[{2}] " -f ( $i + 2 ) , $FirstDiffColNo , $lastDiffColNo
$rangeR1C1 = " R[{0}]C[{1}]:R[{0}]C[{2}] " -f ( $i + 2 ) , $FirstDiffColNo , $lastDiffColNo
$range = [ OfficeOpenXml.ExcelAddress ] :: TranslateFromR1C1 ( $rangeR1C1 , 0 , 0 )
$range = [ OfficeOpenXml.ExcelAddress ] :: TranslateFromR1C1 ( $rangeR1C1 , 0 , 0 )
Set-ExcelRange -WorkS heet $ws -Range $range -BackgroundColor $AddBackgroundColor
Set-ExcelRange -Works heet $ws -Range $range -BackgroundColor $AddBackgroundColor
}
}
Set-ExcelRange -WorkS heet $ws -Range ( " A " + ( $i + 2 ) ) -BackgroundColor $AddBackgroundColor
Set-ExcelRange -Works heet $ws -Range ( " A " + ( $i + 2 ) ) -BackgroundColor $AddBackgroundColor
}
}
}
}
Close-ExcelPackage -ExcelPackage $xl -Show: $Show
Close-ExcelPackage -ExcelPackage $xl -Show: $Show
@@ -284,9 +309,9 @@
Function Merge-MultipleSheets {
Function Merge-MultipleSheets {
<#
<#
. Synopsis
. Synopsis
Merges w orksheets into a single w orksheet with differences marked up .
Merges W orksheets into a single W orksheet with differences marked up .
. Description
. Description
The Merge w orksheet command combines 2 sheets . Merge-MultipleSheets is designed to merge more than 2 .
The Merge W orksheet command combines 2 sheets . Merge-MultipleSheets is designed to merge more than 2 .
So if asked to merge sheets A,B,C which contain Services, with a Name, Displayname and Start mode, where "name" is treated as the key
So if asked to merge sheets A,B,C which contain Services, with a Name, Displayname and Start mode, where "name" is treated as the key
Merge-MultipleSheets calls Merge-Worksheet to merge Name, Displayname and Start mode, from sheets A and C
Merge-MultipleSheets calls Merge-Worksheet to merge Name, Displayname and Start mode, from sheets A and C
the result has column headings -Row, Name, DisplayName, Startmode, C-DisplayName, C-StartMode C-Is, C-Row
the result has column headings -Row, Name, DisplayName, Startmode, C-DisplayName, C-StartMode C-Is, C-Row
@@ -306,22 +331,22 @@ Function Merge-MultipleSheets {
However if Sheet B is the reference sheet, A and C will be seen to have an item removed;
However if Sheet B is the reference sheet, A and C will be seen to have an item removed;
and if B is processed before C, the extra item is known when C is processed and so C is considered to be missing that item .
and if B is processed before C, the extra item is known when C is processed and so C is considered to be missing that item .
. Example
. Example
dir Server* . xlsx | Merge-MulipleSheets -WorkS heetName Services -OutputFile Test2 . xlsx -OutputSheetName Services -Show
dir Server* . xlsx | Merge-MulipleSheets -Works heetName Services -OutputFile Test2 . xlsx -OutputSheetName Services -Show
We are auditing servers and each one has a workbook in the current directory which contains a "Services" w orksheet (the result of
We are auditing servers and each one has a workbook in the current directory which contains a "Services" W orksheet (the result of
Get-WmiObject -Class win32_service | Select-Object -Property Name, Displayname, Startmode
Get-WmiObject -Class win32_service | Select-Object -Property Name, Displayname, Startmode
No key is specified so the key is assumed to be the "Name" column . The files are merged and the result is opened on completion .
No key is specified so the key is assumed to be the "Name" column . The files are merged and the result is opened on completion .
. Example
. Example
dir Serv* . xlsx | Merge-MulipleSheets -WorkS heetName Software -Key "*" -ExcludeProperty Install* -OutputFile Test2 . xlsx -OutputSheetName Software -Show
dir Serv* . xlsx | Merge-MulipleSheets -Works heetName Software -Key "*" -ExcludeProperty Install* -OutputFile Test2 . xlsx -OutputSheetName Software -Show
The server audit files in the previous example also have "Software" w orksheet, but no single field on that sheet works as a key .
The server audit files in the previous example also have "Software" W orksheet, but no single field on that sheet works as a key .
Specifying "*" for the key produces a compound key using all non-excluded fields (and the installation date and file location are excluded) .
Specifying "*" for the key produces a compound key using all non-excluded fields (and the installation date and file location are excluded) .
. Example
. Example
Merge-MulipleSheets -Path hotfixes . xlsx -WorkS heetName Serv* -Key hotfixid -OutputFile test2 . xlsx -OutputSheetName hotfixes -HideRowNumbers -Show
Merge-MulipleSheets -Path hotfixes . xlsx -Works heetName Serv* -Key hotfixid -OutputFile test2 . xlsx -OutputSheetName hotfixes -HideRowNumbers -Show
This time all the servers have written their hofix information to their own w orksheets in a shared Excel workbook named "Hotfixes"
This time all the servers have written their hofix information to their own W orksheets in a shared Excel workbook named "Hotfixes"
(the information was obtained by running Get-Hotfix | Sort-Object -Property description,hotfixid | Select-Object -Property Description,HotfixID)
(the information was obtained by running Get-Hotfix | Sort-Object -Property description,hotfixid | Select-Object -Property Description,HotfixID)
This ignores any sheets which are not named "Serv*", and uses the HotfixID as the key ; in this version the row numbers are hidden .
This ignores any sheets which are not named "Serv*", and uses the HotfixID as the key ; in this version the row numbers are hidden .
#>
#>
[ cmdletbinding ( ) ]
[ cmdletbinding ( ) ]
[ Alias( " Merge-MulipleSheets" ) ]
#[ Alias(" Merge-MulipleSheets")] #There was a spelling error in the first release. This was there to ensure things didn't break but intelisense gave the alias first.
param (
param (
#Paths to the files to be merged.
#Paths to the files to be merged.
[ Parameter ( Mandatory = $true , ValueFromPipeline = $true ) ]
[ Parameter ( Mandatory = $true , ValueFromPipeline = $true ) ]
@@ -335,12 +360,12 @@ Function Merge-MultipleSheets {
#Automatically generate property names (P1, P2, P3, ..) instead of the using the values the top row of the sheet.
#Automatically generate property names (P1, P2, P3, ..) instead of the using the values the top row of the sheet.
[ switch ] $NoHeader ,
[ switch ] $NoHeader ,
#Name(s) of w orksheets to compare,
#Name(s) of W orksheets to compare,
$WorkS heetName = " Sheet1 " ,
$Works heetName = " Sheet1 " ,
#File to write output to
#File to write output to
[ Alias ( 'OutFile' ) ]
[ Alias ( 'OutFile' ) ]
$OutputFile = " .\temp.xlsx " ,
$OutputFile = " .\temp.xlsx " ,
#Name of w orksheet to output - if none specified will use the reference w orksheet name.
#Name of W orksheet to output - if none specified will use the reference W orksheet name.
[ Alias ( 'OutSheet' ) ]
[ Alias ( 'OutSheet' ) ]
$OutputSheetName = " Sheet1 " ,
$OutputSheetName = " Sheet1 " ,
#Properties to include in the DIFF - supports wildcards, default is "*".
#Properties to include in the DIFF - supports wildcards, default is "*".
@@ -367,50 +392,51 @@ Function Merge-MultipleSheets {
begin { $filestoProcess = @ ( ) }
begin { $filestoProcess = @ ( ) }
process { $filestoProcess + = $Path }
process { $filestoProcess + = $Path }
end {
end {
if ( $filestoProcess . Count -eq 1 -and $WorkS heetName -match '\*' ) {
if ( $filestoProcess . Count -eq 1 -and $Works heetName -match '\*' ) {
Write-Progress -Activity " Merging sheets " -CurrentOperation " Expanding * to names of sheets in $( $filestoProcess [ 0 ] ) . "
Write-Progress -Activity " Merging sheets " -CurrentOperation " Expanding * to names of sheets in $( $filestoProcess [ 0 ] ) . "
$excel = Open-ExcelPackage -Path $filestoProcess
$excel = Open-ExcelPackage -Path $filestoProcess
$WorksheetName = $excel . Workbook . Worksheets . Name . where ( { $_ -like $WorkS heetName } )
$WorksheetName = $excel . Workbook . Worksheets . Name . where ( { $_ -like $Works heetName } )
Close-ExcelPackage -NoSave -ExcelPackage $excel
Close-ExcelPackage -NoSave -ExcelPackage $excel
}
}
#Merge in dentically named sheets in different work books;
#Merge identically named sheets in different work books;
if ( $filestoProcess . Count -ge 2 -and $WorkS heetName -is " string " ) {
if ( $filestoProcess . Count -ge 2 -and $Works heetName -is " string " ) {
Get-Variable -Name 'HeaderName' , 'NoHeader' , 'StartRow' , 'Key' , 'Property' , 'ExcludeProperty' , 'WorkS heetName' -ErrorAction SilentlyContinue |
Get-Variable -Name 'HeaderName' , 'NoHeader' , 'StartRow' , 'Key' , 'Property' , 'ExcludeProperty' , 'Works heetName' -ErrorAction SilentlyContinue |
Where-Object { $_ . Value } | ForEach-Object -Begin { $params = @ { } } -Process { $params [ $_ . Name ] = $_ . Value }
Where-Object { $_ . Value } | ForEach-Object -Begin { $params = @ { } } -Process { $params [ $_ . Name ] = $_ . Value }
Write-Progress -Activity " Merging sheets " -CurrentOperation " C omparing $( $filestoProcess [ -1 ] ) against $( $filestoProcess [ 0 ] ) . "
Write-Progress -Activity " Merging sheets " -CurrentOperation " c omparing ' $WorksheetName ' in $( $filestoProcess [ -1 ] ) against $( $filestoProcess [ 0 ] ) . "
$merged = Merge-Worksheet @params -Referencefile $filestoProcess [ 0 ] -Differencefile $filestoProcess [ -1 ]
$merged = Merge-Worksheet @params -Referencefile $filestoProcess [ 0 ] -Differencefile $filestoProcess [ -1 ]
$nextFileNo = 2
$nextFileNo = 2
while ( $nextFileNo -lt $filestoProcess . count -and $merged ) {
while ( $nextFileNo -lt $filestoProcess . count -and $merged ) {
Write-Progress -Activity " Merging sheets " -CurrentOperation " C omparing $( $filestoProcess [ - $nextFileNo ] ) against $( $filestoProcess [ 0 ] ) . "
Write-Progress -Activity " Merging sheets " -CurrentOperation " c omparing ' $WorksheetName ' in $( $filestoProcess [ - $nextFileNo ] ) against $( $filestoProcess [ 0 ] ) . "
$merged = Merge-Worksheet @params -ReferenceObject $merged -Differencefile $filestoProcess [ - $nextFileNo ]
$merged = Merge-Worksheet @params -ReferenceObject $merged -Differencefile $filestoProcess [ - $nextFileNo ]
$nextFileNo + +
$nextFileNo + +
}
}
}
}
#Merge different sheets from one workbook
#Merge different sheets from one workbook
elseif ( $filestoProcess . Count -eq 1 -and $WorkS heetName . Count -ge 2 ) {
elseif ( $filestoProcess . Count -eq 1 -and $Works heetName . Count -ge 2 ) {
Get-Variable -Name 'HeaderName' , 'NoHeader' , 'StartRow' , 'Key' , 'Property' , 'ExcludeProperty' -ErrorAction SilentlyContinue |
Get-Variable -Name 'HeaderName' , 'NoHeader' , 'StartRow' , 'Key' , 'Property' , 'ExcludeProperty' -ErrorAction SilentlyContinue |
Where-Object { $_ . Value } | ForEach-Object -Begin { $params = @ { } } -Process { $params [ $_ . Name ] = $_ . Value }
Where-Object { $_ . Value } | ForEach-Object -Begin { $params = @ { } } -Process { $params [ $_ . Name ] = $_ . Value }
Write-Progress -Activity " Merging sheets " -CurrentOperation " Comparing $( $WorkS heetName [ -1 ] ) against $( $WorkS heetName [ 0 ] ) . "
Write-Progress -Activity " Merging sheets " -CurrentOperation " Comparing $( $Works heetName [ -1 ] ) against $( $Works heetName [ 0 ] ) . "
$merged = Merge-Worksheet @params -Referencefile $filestoProcess [ 0 ] -Differencefile $filestoProcess [ 0 ] -WorkS heetName $WorkS heetName [ 0 , -1 ]
$merged = Merge-Worksheet @params -Referencefile $filestoProcess [ 0 ] -Differencefile $filestoProcess [ 0 ] -Works heetName $Works heetName [ 0 , -1 ]
$nextSheetNo = 2
$nextSheetNo = 2
while ( $nextSheetNo -lt $WorkS heetName . count -and $merged ) {
while ( $nextSheetNo -lt $Works heetName . count -and $merged ) {
Write-Progress -Activity " Merging sheets " -CurrentOperation " Comparing $( $WorkS heetName [ - $nextSheetNo ] ) against $( $WorkS heetName [ 0 ] ) . "
Write-Progress -Activity " Merging sheets " -CurrentOperation " Comparing $( $Works heetName [ - $nextSheetNo ] ) against $( $Works heetName [ 0 ] ) . "
$merged = Merge-Worksheet @params -ReferenceObject $merged -Differencefile $filestoProcess [ 0 ] -WorkS heetName $WorkS heetName [ - $nextSheetNo ] -DiffPrefix $WorkS heetName [ - $nextSheetNo ]
$merged = Merge-Worksheet @params -ReferenceObject $merged -Differencefile $filestoProcess [ 0 ] -Works heetName $Works heetName [ - $nextSheetNo ] -DiffPrefix $Works heetName [ - $nextSheetNo ]
$nextSheetNo + +
$nextSheetNo + +
}
}
}
}
#We either need one w orksheet name and many files or one file and many sheets.
#We either need one W orksheet name and many files or one file and many sheets.
else { Write-Warning -Message " Need at least two files to process " ; return }
else { Write-Warning -Message " Need at least two files to process " ; return }
#if the process didn't return data then abandon now.
#if the process didn't return data then abandon now.
if ( -not $merged ) { Write-Warning -Message " The merge operation did not return any data. " ; return }
if ( -not $merged ) { Write-Warning -Message " The merge operation did not return any data. " ; return }
$orderByProperties = $merged [ 0 ] . psobject . properties . where ( { $_ . name -match " row $ " } ) . name
$orderByProperties = $merged [ 0 ] . psobject . properties . where ( { $_ . name -match " row $ " } ) . name
Write-Progress -Activity " Merging sheets " -CurrentOperation " C reating output sheet '$OutputSheetName ' in $OutputFile "
Write-Progress -Activity " Merging sheets " -CurrentOperation " c reating output sheet '$OutputSheetName ' in $OutputFile "
$excel = $merged | Sort-Object -Property $orderByProperties | Update-FirstObjectProperties |
$excel = $merged | Sort-Object -Property $orderByProperties |
Export-Excel -Path $OutputFile -WorkS heetname $OutputSheetName -ClearSheet -BoldTopRow -AutoFilter -PassThru
Export-Excel -Path $OutputFile -Works heetname $OutputSheetName -ClearSheet -BoldTopRow -AutoFilter -PassThru
$sheet = $excel . Workbook . Worksheets [ $OutputSheetName ]
$sheet = $excel . Workbook . Worksheets [ $OutputSheetName ]
#We will put in a conditional format for "if all the others are not flagged as 'same'" to mark rows where something is added, removed or changed
#We will put in a conditional format for "if all the others are not flagged as 'same'" to mark rows where something is added, removed or changed
@@ -424,8 +450,8 @@ Function Merge-MultipleSheets {
if ( $filesToProcess . Count -ge 2 ) {
if ( $filesToProcess . Count -ge 2 ) {
$refPrefix = ( Split-Path -Path $filestoProcess [ 0 ] -Leaf ) -replace " \.xlsx $ " , " "
$refPrefix = ( Split-Path -Path $filestoProcess [ 0 ] -Leaf ) -replace " \.xlsx $ " , " "
}
}
else { $refPrefix = $WorkS heetName [ 0 ] }
else { $refPrefix = $Works heetName [ 0 ] }
Write-Progress -Activity " Merging sheets " -CurrentOperation " A pplying formatting to sheet '$OutputSheetName ' in $OutputFile "
Write-Progress -Activity " Merging sheets " -CurrentOperation " a pplying formatting to sheet '$OutputSheetName ' in $OutputFile "
#Find the column headings which are in the form "diffFile is"; which will hold 'Same', 'Added' or 'Changed'
#Find the column headings which are in the form "diffFile is"; which will hold 'Same', 'Added' or 'Changed'
foreach ( $cell in $sheet . Cells [ ( $sheet . Dimension . Address -replace " \d+ $ " , " 1 " ) ] . Where ( { $_ . value -match " \sIS $ " } ) ) {
foreach ( $cell in $sheet . Cells [ ( $sheet . Dimension . Address -replace " \d+ $ " , " 1 " ) ] . Where ( { $_ . value -match " \sIS $ " } ) ) {
#Work leftwards across the headings applying conditional formatting which says
#Work leftwards across the headings applying conditional formatting which says
@@ -434,7 +460,7 @@ Function Merge-MultipleSheets {
$columnNo = $cell . start . Column -1
$columnNo = $cell . start . Column -1
$cellAddr = [ OfficeOpenXml.ExcelAddress ] :: TranslateFromR1C1 ( " R1C $columnNo " , 1 , $columnNo )
$cellAddr = [ OfficeOpenXml.ExcelAddress ] :: TranslateFromR1C1 ( " R1C $columnNo " , 1 , $columnNo )
while ( $sheet . cells [ $cellAddr ] . value -match $prefix ) {
while ( $sheet . cells [ $cellAddr ] . value -match $prefix ) {
$condFormattingParams = @ { RuleType = 'Expression' ; BackgroundPattern = 'Solid' ; WorkS heet = $sheet ; Range = $ ( [ OfficeOpenXml.ExcelAddress ] :: TranslateFromR1C1 ( " R[1]C[ $columnNo ]:R[1048576]C[ $columnNo ] " , 0 , 0 ) ) }
$condFormattingParams = @ { RuleType = 'Expression' ; BackgroundPattern = 'Solid' ; Works heet = $sheet ; StopIfTrue = $true ; Range = $ ( [ OfficeOpenXml.ExcelAddress ] :: TranslateFromR1C1 ( " R[1]C[ $columnNo ]:R[1048576]C[ $columnNo ] " , 0 , 0 ) ) }
Add-ConditionalFormatting @condFormattingParams -ConditionValue ( $cell . Address + '="Added"' ) -BackgroundColor $AddBackgroundColor
Add-ConditionalFormatting @condFormattingParams -ConditionValue ( $cell . Address + '="Added"' ) -BackgroundColor $AddBackgroundColor
Add-ConditionalFormatting @condFormattingParams -ConditionValue ( $cell . Address + '="Changed"' ) -BackgroundColor $ChangeBackgroundColor
Add-ConditionalFormatting @condFormattingParams -ConditionValue ( $cell . Address + '="Changed"' ) -BackgroundColor $ChangeBackgroundColor
Add-ConditionalFormatting @condFormattingParams -ConditionValue ( $cell . Address + '="Removed"' ) -BackgroundColor $DeleteBackgroundColor
Add-ConditionalFormatting @condFormattingParams -ConditionValue ( $cell . Address + '="Removed"' ) -BackgroundColor $DeleteBackgroundColor
@@ -450,15 +476,16 @@ Function Merge-MultipleSheets {
$nameRegex = $colNames -Join '|'
$nameRegex = $colNames -Join '|'
foreach ( $cell in $sheet . Cells [ ( $sheet . Dimension . Address -replace " \d+ $ " , " 1 " ) ] . Where ( { $_ . value -Notmatch $nameRegex } ) ) {
foreach ( $cell in $sheet . Cells [ ( $sheet . Dimension . Address -replace " \d+ $ " , " 1 " ) ] . Where ( { $_ . value -Notmatch $nameRegex } ) ) {
$cell . Value = $refPrefix + $cell . Value
$cell . Value = $refPrefix + $cell . Value
$condFormattingParams = @ { RuleType = 'Expression' ; BackgroundPattern = 'None ' ; WorkS heet = $sheet ; Range = [ OfficeOpenXml.ExcelAddress ] :: TranslateFromR1C1 ( " R[2]C[ $( $cell . start . column ) ]:R[1048576]C[ $( $cell . start . column ) ] " , 0 , 0 ) }
$condFormattingParams = @ { RuleType = 'Expression' ; BackgroundPattern = 'Solid ' ; Works heet = $sheet ; StopIfTrue = $true ; Range = [ OfficeOpenXml.ExcelAddress ] :: TranslateFromR1C1 ( " R[2]C[ $( $cell . start . column ) ]:R[1048576]C[ $( $cell . start . column ) ] " , 0 , 0 ) }
Add-ConditionalFormatting @condFormattingParams -ConditionValue ( " OR( " + ( ( $sameChecks -join " , " ) -replace '<>"Same"' , '="Added"' ) + " ) " ) -BackgroundColor $DeleteBackgroundColor
Add-ConditionalFormatting @condFormattingParams -ConditionValue ( " OR( " + ( ( $sameChecks -join " , " ) -replace '<>"Same"' , '="Added"' ) + " ) " ) -BackgroundColor $DeleteBackgroundColor
Add-ConditionalFormatting @condFormattingParams -ConditionValue ( " AND( " + ( ( $sameChecks -join " , " ) -replace '<>"Same"' , '="Changed"' ) + " ) " ) -BackgroundColor $ChangeBackgroundColor
}
}
#We've made a bunch of things wider so now is the time to autofit columns. Any hiding has to come AFTER this, because it unhides things
#We've made a bunch of things wider so now is the time to autofit columns. Any hiding has to come AFTER this, because it unhides things
$sheet . Cells . AutoFitColumns ( )
$sheet . Cells . AutoFitColumns ( )
#if we have a key field (we didn't concatenate all fields) use what we built up in $sameChecks to apply conditional formatting to it (Row no will be in column A, Key in Column B)
#if we have a key field (we didn't concatenate all fields) use what we built up in $sameChecks to apply conditional formatting to it (Row no will be in column A, Key in Column B)
if ( $Key -ne '*' ) {
if ( $Key -ne '*' ) {
Add-ConditionalFormatting -WorkS heet $sheet -Range " B2:B1048576 " -ForeGroundColor $KeyFontColor -BackgroundPattern 'None' -RuleType Expression -ConditionValue ( " OR( " + ( $sameChecks -join " , " ) + " ) " )
Add-ConditionalFormatting -Works heet $sheet -Range " B2:B1048576 " -ForeGroundColor $KeyFontColor -BackgroundPattern 'None' -RuleType Expression -ConditionValue ( " OR( " + ( $sameChecks -join " , " ) + " ) " )
$sheet . view . FreezePanes ( 2 , 3 )
$sheet . view . FreezePanes ( 2 , 3 )
}
}
else { $sheet . view . FreezePanes ( 2 , 2 ) }
else { $sheet . view . FreezePanes ( 2 , 2 ) }