1

I've found that using $null is impossible for string in PowerShell. While I've worked with workaround as below I wonder if there's better way?

Essentially I need 3 states of string $null, '' (empty), 'some string string'.

  • First one means - do not execute.
  • 2nd one - clear text
  • Replace Text with new value

Below is workaround code where I opted for switch -ClearText. Keep in mind that while I could just not add the Set-WordTextText if field is $null but since I'm doing this in nested scenario I would prefer doing it as $null.

function Remove-WordText {
    Param(
        [parameter(ValueFromPipelineByPropertyName, ValueFromPipeline)][Xceed.Words.NET.InsertBeforeOrAfter] $Paragraph,
        [int] $Index = 0,
        [int] $Count = $($Paragraph.Text.Length),
        [bool] $TrackChanges,
        [bool] $RemoveEmptyParagraph,
        [bool] $Supress = $false
    )
    if ($Paragraph -ne $null) {
        Write-Verbose "Remove-WordText - Current text $($Paragraph.Text) "
        Write-Verbose "Remove-WordText - Removing from $Index to $Count - Paragraph Text Count: $($Paragraph.Text.Length)"
        $Paragraph.RemoveText($Index, $Count, $TrackChanges, $RemoveEmptyParagraph)
    }
    if ($Supress) { return } else { return $Paragraph }
}

function Set-WordTextText {
    param(
        [parameter(ValueFromPipelineByPropertyName, ValueFromPipeline)][Xceed.Words.NET.InsertBeforeOrAfter] $Paragraph,
        [alias ("S")] [AllowNull()][string] $Text,
        [switch] $ClearText,
        [bool] $Supress = $false
    )
    if ($Paragraph -ne $null) {
        if (-not [string]::IsNullOrEmpty($Text)) {
            if ($ClearText -eq $true) {
                Write-Verbose 'Set-WordTextText - Clearing Text $ClearText is True'
                $Paragraph = Remove-WordText -Paragraph $Paragraph
            }
            Write-Verbose "Set-WordTextText - Appending Value $Text"
            $Paragraph = $Paragraph.Append($Text)
        }
    }
    if ($Supress) { return } else { return $Paragraph }
}

enter image description here

I essentially execute it within function:

$Paragraph[$i] = $Paragraph[$i] | Set-WordTextText -Text $Text[$i] -ClearText:$ClearText -Supress $false
$Paragraph[$i] = $Paragraph[$i] | Set-WordTextColor -Color $Color[$i] -Supress $false
$Paragraph[$i] = $Paragraph[$i] | Set-WordTextFontSize -FontSize $FontSize[$i] -Supress $false
$Paragraph[$i] = $Paragraph[$i] | Set-WordTextFontFamily -FontFamily $FontFamily[$i] -Supress $false
$Paragraph[$i] = $Paragraph[$i] | Set-WordTextBold -Bold $Bold[$i] -Supress $false
$Paragraph[$i] = $Paragraph[$i] | Set-WordTextItalic -Italic $Italic[$i] -Supress $false

It only executes action if value is not null. So the "wrapper" function can have from 1 to 20 parameters and execute only if the parameter is given.

2 Answers 2

3

If you specify the type [String] for a parameter that parameter becomes a typed variable and can't be $null anymore. Even if you pass $null to the parameter the value will automatically be converted to an empty string. To allow a parameter to be either $null or a string (empty or not) you'd need something like this:

function Set-WordTextText {
    Param(
        ...
        [Parameter(Mandatory=$false)]
        [AllowNull()]
        $Text = $null,
        ...
    )

    if ($_ -ne $null -and $_ -isnot [String]) {
        throw 'Invalid argument for parameter -Text.'
    }

    ...
}
Sign up to request clarification or add additional context in comments.

1 Comment

Makes sense. For some reason I was so focused on having it typed as [string] that I wouldn't accept no type. Thanks
0

Deciding what to do if $Paragraph is in one of the three states depends on the function you are performing. Something like this might help

if ($null -eq $Paragraph) { 
    Write-Host "Paragraph is Null, do not execute"
    return
}
elseif ([string]::IsNullOrEmpty($Paragraph.Text)) { 
    # this depends on the function you are in.
    # if inside Remove-WordText() you don't have to do anything because it is already empty
    # you can check the function currently executed with $MyInvocation.MyCommand.Name
    if ($MyInvocation.MyCommand.Name -eq 'Remove-WordText') {
        Write-Host "Paragraph.Text is Null or Empty, clear text"
        $Paragraph.RemoveText($Index, $Count, $TrackChanges, $RemoveEmptyParagraph)
    else {
        # however, if you're inside Set-WordTextText() you need to decide if $Text
        # is not empty aswell and if not, you append the Text tp $Paragraph
        if (-not [string]::IsNullOrEmpty($Text)) {
            Write-Verbose "Set-WordTextText - Appending Value $Text"
            $Paragraph = $Paragraph.Append($Text)
        }
    }
}
else {
    Write-Host "Paragraph.Text has value, appending text"
    $Paragraph = $Paragraph.Append($Text)
}

Hope that helps

1 Comment

I don't think I follow your logic. $Paragraph being null is an option and works just fine. It's separate value $Text which is a string can't be null and I need it to be null to stop execution. Otherwise I need to provide additional parameter. If I would be able to use $null I could simply skip providing parameter to function and it wouldn't execute. As it is now if I leave parameter not defined and I would skip using -Clear it would essentially wipe value instead of skipping it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.