5

I have an excel vba code that finds a particular cell in a sheet. It uses the Find method form the excel libraries. Here is the code

objRange.Find(What:="*", SearchDirection:=xlPrevious, SearchOrder:=xlByRows)

I need to do the same thing in powershell. But this method has a total of 9 arguments. How to ignore the other optional arguments in powershell. Something like this?

$range.Find("*", "", "", "", $xlByRows, $xlPrevious, "", "", "")

Here is the documentation of Range.Find Method

Ammar
  • 485
  • 1
  • 5
  • 14

2 Answers2

9

$null doesn't work, but according to this answer you can use [Type]::Missing:

$default = [Type]::Missing
$xl.Cells.Find("*", $default, $default, $default, $xlByRows, $xlPrevious,
               $default, $default, $default)
Community
  • 1
  • 1
Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
  • There must be some way to give default values to arguments which are not required – Ammar Jul 06 '13 at 04:20
  • @Ammar, any luck figuring out a way to name only the optional values you care about, similarly to the VBA `:=` syntax? – Jay Carlton Jun 19 '14 at 13:57
  • @Jay, I just used the solution provided by Ansgar. – Ammar Jun 24 '14 at 01:53
  • @Jay, according to http://stackoverflow.com/questions/24520664/call-c-sharp-method-from-powershell-without-supplying-optional-arguments it might not be possible. – irh Jul 07 '14 at 14:38
  • @irh yeah, this is the kind of thing that requires actual syntax built into the language. I'd tend to think we'd see examples of how to do it if it could be done. There might be a way to build a FunctionWithOptionalArgumentCaller class that does this for me. Maybe it could use reflection to figure out the types and default values for the optional ones and expose a method to set the ones I cared about. Hardly seems worth it though. – Jay Carlton Jul 07 '14 at 19:13
  • @JayCarlton If you want to use named params use this: https://stackoverflow.com/questions/5544844/how-to-call-a-complex-com-method-from-powershell – Sancarn Nov 03 '20 at 19:26
1

I addressed this by creating overload methods that calls the core method with the value I want. e.g. I want the user to be able to specify the number of processed records or call the "Increment" method and then just call "WriteProgress" with no argument:

class UserFeedback {
[string]$Name
[int]$ThingCount
[datetime]$ProcessStartDateTime
[int]$ProcessedCount

UserFeedback ([string] $Name,[int]$ThingCount){
    $this.ProcessStartDateTime = Get-Date
    $this.Name = $Name
    $this.ThingCount = $ThingCount
    $this.ProcessedCount = 0
}

WriteProgress([int] $intProcessed){
    $this.ProcessStartDateTime        
    $SecondsElapsed = ((Get-Date) - $this.ProcessStartDateTime).TotalSeconds
    $SecondsRemaining = ($SecondsElapsed / ($intProcessed / $this.ThingCount)) - $SecondsElapsed
    Write-Progress -Activity $this.Name -PercentComplete (($intProcessed/$($this.ThingCount)) * 100) -CurrentOperation "$("{0:N2}" -f ((($intProcessed/$($this.ThingCount)) * 100),2))% Complete" -SecondsRemaining $SecondsRemaining
}

WriteProgress(){
    $this.WriteProgress($this.ProcessedCount)
}

Increment(){
    $this.ProcessedCount ++    
}

}

NitrusCS
  • 597
  • 1
  • 5
  • 20
  • The old ways are the best ways, a nice pragmatic solution that's more elegant than others - thanks for the reminder – Oly Dungey Nov 06 '19 at 15:19