Использование параметра ByRef в лямбда-выражении не допускается.Обходной путь не дает параметру правильное состояние - PullRequest
0 голосов
/ 28 февраля 2019

Глядя на этот вопрос переполнения стека , который ссылается на этот MSDN Doc , выясняется, что я не могу передать параметр, отправляемый в вызывающее Sub int, выражение Lambda, потому что онопараметр ByRef.

Я создал временный параметр (на самом деле два - есть два, которые требуются в лямбда-выражении) и передал его в длительное задание.

Задача выполняетсяотлично.Он использует выражение Parallel.ForEach, которое выполняется в 30% от исходного времени.

Проблема заключается в том, что оба эти параметра ByRef необходимы ниже этого вызова.

Parallel.ForEach вставляет сотни значений в Excel.Приведенные ниже операторы должны выполнять форматирование, а также активировать каждую ячейку, чтобы открывать диалоговое окно с дополнительной информацией.Ни форматирование, ни кликабельность не работают.

Вот подпись вызывающего Sub, лямбда-выражение и некоторый код, который вызывается впоследствии:

    Friend Sub RefreshFormattingSummaryReport(ByRef oDPWorksheet As CDPWorksheet, ByRef oSheet As Microsoft.Office.Interop.Excel.Worksheet,
                                          ByRef worker As BackgroundWorker)



    Dim tempDPWorksheet As New CDPWorksheet
    tempDPWorksheet = oDPWorksheet
    Dim tempOsheet As New Microsoft.Office.Interop.Excel.Worksheet
    tempOsheet = oSheet


                Parallel.ForEach(rangeList,
                Sub(singleTuple)
                    Dim iRow1 As Integer = 0
                    Dim iRow2 As Integer = 0
                    Dim iMaxRow As Integer = 0
                    Dim iCol1 As Integer = 0
                    Dim iCol2 As Integer = 0
                    Dim oRange As Range
                    Dim oRange2 As Range
                    Dim oCellValues() As String = Nothing
                    Dim oDesignSheet As Microsoft.Office.Interop.Excel.Worksheet
                    Dim bLoadFormulas As Boolean = False

                    Dim NamedRange = singleTuple.NamedRange
                    Dim NamedRangeRow = singleTuple.NamedRangeRow
                    Dim NamedRangeColumn = singleTuple.NamedRangeColumn
                    Dim NamedRangeCellValue = singleTuple.NamedRangeCellValue

                    If InStr(NamedRange, tempDPWorksheet.SheetID) > 0 Then

                        iRow1 = Integer.Parse(NamedRangeRow.ToString.Substring(0, IIf(InStr(NamedRangeRow, "-") > 0, InStr(NamedRangeRow, "-") - 1, Len(NamedRangeRow))))
                        iRow2 = Integer.Parse(NamedRangeRow.ToString.Substring(IIf(InStr(NamedRangeRow, "-") > 0, InStr(NamedRangeRow, "-"), 0), IIf(InStr(NamedRangeRow, "-") > 0, Len(NamedRangeRow) - InStr(NamedRangeRow, "-"), Len(NamedRangeRow))))
                        If iRow2 > iMaxRow Then iMaxRow = iRow2

                        If InStr(NamedRangeColumn, "DP_COL") > 0 Then
                            oRange = tempOsheet.Range(NamedRangeColumn)
                            iCol1 = oRange.Column
                            iCol2 = iCol1
                            oRange = Nothing
                        Else
                            iCol1 = Integer.Parse(NamedRangeColumn.ToString.Substring(0, IIf(InStr(NamedRangeColumn, "-") > 0, InStr(NamedRangeColumn, "-") - 1, Len(NamedRangeColumn))))
                            iCol2 = Integer.Parse(NamedRangeColumn.ToString.Substring(IIf(InStr(NamedRangeColumn, "-") > 0, InStr(NamedRangeColumn, "-"), 0), IIf(InStr(NamedRangeColumn, "-") > 0, Len(NamedRangeColumn) - InStr(NamedRangeColumn, "-"), Len(NamedRangeColumn))))
                        End If

                        oRange = CType(tempOsheet.Range(tempOsheet.Cells(iRow1, iCol1), tempOsheet.Cells(iRow2, iCol2)), Microsoft.Office.Interop.Excel.Range)
                        oCellValues = Split(Replace(Replace(Replace(Replace(Replace(Replace(NamedRangeCellValue, "{", ""), "}", ""), "&amp;", "&"), "amp;", ""), "&lt;", "<"), "&gt;", ">"), ",| ")

                        If oRange IsNot Nothing Then
                            If oCellValues.Length = oRange.Rows.Count Then

                                For j = 1 To oRange.Rows.Count

                                    Try
                                        oRange2 = oRange.Cells.Item(j)
                                        If oCellValues(j - 1).Length >= 2 Then
                                            oRange2.Value = IIf(oCellValues(j - 1).Substring(0, 2).Equals("  "), oCellValues(j - 1), LTrim(oCellValues(j - 1)))
                                        Else
                                            oRange2.Value = oCellValues(j - 1)
                                        End If
                                    Catch ex As Exception
                                        'MessageBox.Show(String.Format("Error: {0}", ex.Message, oRange.Cells.Item(j)))
                                    End Try

                                Next

                            End If
                        End If

                        tempOsheet.Names.Add(Replace(NamedRange, tempDPWorksheet.SheetID & ".", "").Replace(" ", "_").Replace("-", "_").Replace(",", ""), oRange)

                        Try


                            If tempDPWorksheet.Columns.Contains(NamedRangeColumn) Then
                                bLoadFormulas = (tempDPWorksheet.Columns.IndexOf(NamedRangeColumn) <> -1) AndAlso (DirectCast(tempDPWorksheet.Columns(tempDPWorksheet.Columns.IndexOf(NamedRangeColumn)), CColumn).Type = EColumnTypes.Excel) Or NameIsExcelRow(NamedRange.ToString)
                            Else
                                bLoadFormulas = False
                            End If

                            If Not (InStr(NamedRange, "DP_FRO") > 0 Or InStr(NamedRange, "DRILLPOINT") > 0) Then
                                ' ************** Repetitive Copy/Paste operations
                                RangeCopyDesignFormat(oRange, oDesignSheet.Range(Replace(NamedRange, tempDPWorksheet.SheetID & ".", "")), False, Not tempDPWorksheet.IncludeFormatting Or Not (Not (InStr(NamedRange, "SKIP") > 0) Or tempDPWorksheet.FormatSkipped), False, "", bLoadformulas:=bLoadFormulas, bLoadComments:=True)
                            End If

                        Catch ex As Exception

                        End Try

                    End If
                End Sub)

И некоторые вызовы, которые выполняются впоследствии:

    oSheet = tempOsheet
    oDPWorksheet = tempDPWorksheet

    ReplaceKeywordsInHeaderAndFooter("", oDBInfo, oSheet, "", "", oProp.Value)

    If oDPWorksheet.IncludeDrilldown Then
        DrillDownLoad(oSheet, oDPWorksheet, oSmartTags, oDBInfo, "", 4 + iRowOffset)
    End If

    SuppressRows(oSheet, oDPWorksheet, oDBInfo, iMaxRow, iRowOffset:=iRowOffset)

    If Not oDPWorksheet.DoNotAutofitColumns Then
        tWidth = oSheet.Range("DP_FRO_" & oDPWorksheet.FROutlineID).ColumnWidth
        oSheet.Range("DRILLPOINT").Columns.AutoFit()
        oSheet.Range("DP_FRO_" & oDPWorksheet.FROutlineID).ColumnWidth = tWidth
    End If
    HideColumns(oSheet, oDPWorksheet.Columns, "DP_FRO_" & oDPWorksheet.FROutlineID, oDPWorksheet.HideFROColumn)

Я попытался присвоить временные переменные параметрам ByRef, и я также попытался изменить каждый экземпляр параметров ByRef в остальной части Sub с помощью временных имен.Ни одна из них не работает.

Есть мысли?Любые предложения приветствуются.

...