简体   繁体   中英

Workaround for excel 2013 range value2 on Windows10

I have two computers, one with windows7 and one with windows10. Both computers use Excel 15.0.4753.1003.

The following script fails on Windows10:

function write-toexcelrange(){
    param(
        #The range should be a cell in the upper left corner where you want to "paste" your data
        [ValidateNotNullOrEmpty()]
        $Range,

        # data should be in the form of a jagged multiarray ("row1Column1","row2column2"),("row2column1","row2column2")
        # if data is a simple array of values, it will be interpreted as 1 column with multiple rows
        # Rows can differ in length
        [validatenotnullorempty()]
        [array]$data
    )
    $rows=0
    $cols=0
    if($data -is [array]) {
        foreach($row in $data){
            $rows++
            $cols=[math]::max($cols,([array]$row).length)
        }

        #Create multiarray
        $marr=new-object 'string[,]' $rows,$cols
        for($r=0;$r -lt $marr.GetLength(0);$r++) {
            for($c=0;$c -lt $marr.GetLength(1);$c++) {
                $marr[$r,$c]=[string]::Empty
            }
        }
        for($r=0;$r -lt $rows;$r++) {
            if($data[$r] -is [array]){
                for($c=0;$c -lt ([array]$data[$r]).length;$c++) {
                    $marr[$r,$c]=$data[$r][$c].ToString()
                }
            } else {
                $marr[$r,0]=$data[$r].ToString()
            }
        }
        $wrr=$range.resize($rows,$cols)
        $wrr.value2=$marr

    } else {
        $wrr=$range
        $wrr.value2=$data
    }
    #Return the range written to
    $wrr
}

$excel = New-Object -ComObject Excel.Application
$excel.visible = $true
$defaultsheets=$excel.SheetsInNewWorkbook
$excel.SheetsInNewWorkbook=1
$wb = $Excel.Workbooks.add() 
$excel.SheetsInNewWorkbook=$defaultsheets 
$mysheet = $wb.worksheets.item(1)
$mysheet.name = "test"

write-toexcelrange -Range $mysheet.range("A1") -data $exceldata|out-null

With the following error:

Unable to cast object of type 'System.String[,]' to type 'System.String'.
At C:\data\rangetest.ps1:38 char:9
+         $wrr.value2=$marr
+         ~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OperationStopped: (:) [], InvalidCastException
    + FullyQualifiedErrorId : System.InvalidCastException

It appears as if the value2 property behaves differently in Windows10 which is weird considering it´s the same version of excel.

Now to the question: Is there a fix/workaround to getting the data into the cells, which does not involve looping through all the cells.

Update 1 It was suggested by Grade 'Eh' Bacon that I try the .Formula property. It Works! I also noted that Windows10 uses Powershell v5 while my Windows7 has Powershell v4.

Since that worked for you I'll flesh it out as an answer. To summarize, pay attention to the differences between .text, .value, .value2, and .formula [or .formulaR1C1]. See discussion of the first 3 here:

What is the difference between .text, .value, and .value2?

And discussion of .Formula here:

Can Range.Value2 & Range.Formula have different values in C#, not VBA?

Without getting into why any of these can have different values (in short, formatting and other metadata can have an impact on some of those options in different ways, depending on what type of entry is made to a given cell), after reading those Q&As above, I just always use Formula when referring to what's inside a cell. In most cases, that's what you likely want VBA to look at anyway. Changing .value2 to .formula seems to work here, although I have no idea why that would be the case between Windows versions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM