Sửa lỗi code chuyển từ VBA sang VB.net bị lỗi không cho ra hết kết quả của mảng

Liên hệ QC

quyenpv

Thu nhặt kiến thức
Tham gia
5/1/13
Bài viết
709
Được thích
90
Giới tính
Nam
Nghề nghiệp
Decode cuộc đời!
Tôi có code đang dùng cho VBA chạy rất tốt và đúng yêu cầu, tuy nhiên khi chuyển sang vb.net code chỉ xuất được giá trị đầu tiên của mảng không biết lỗi ở đâu mong anh chị quen vb.net chỉ giúp
Dữ liệu ban đầu
1677990254491.png
Dữ liệu mong muốn xuất ra (Code VBA chạy tốt)
1677990295817.png

Đây là code VBA của tôi
Mã:
Sub Run_THop_GtrPO()
    'Add 25/06/2022: Bo sung tong hop tham dinh ra Sheet Tong hop
    Dim arr_DN(), iR1&, res_DN()
    Set sh_PLPO = Sheets("PO_PLHD")     'Sheet Tham Dinh Quyet toan
    Sheets("PO-BTH").Select
    Thue_VAT = GetRegistry(HKEY_SET_HC, "Thue_VAT") / 100
    'MsgBox sh_TH_DNghiQT.Range("C" & sh_TH_DNghiQT.Rows.count).End(xlUp).row
    arr_DN = sh_PLPO.Range("A9:K" & sh_PLPO.Range("D" & sh_PLPO.Rows.count).End(xlUp).Row).value
    sRow = UBound(arr_DN)
    ReDim res_DN(1 To sRow, 1 To 6)
    For i = 1 To sRow
        If arr_DN(i, 1) = "HM" Then
            k = k + 1
            res_DN(k, 1) = k
            res_DN(k, 2) = arr_DN(i, 3)
            'Don gia truoc thue
            res_DN(k, 3) = Round(arr_DN(i, 10) / (1 + Thue_VAT), 1)
            'Thue VAT
            res_DN(k, 4) = Round((arr_DN(i, 10) / (1 + Thue_VAT)) * Thue_VAT, 1)
            'Tong cong
            res_DN(k, 5) = res_DN(k, 3) + res_DN(k, 4)
        End If
    Next i
    With Sheets("PO-BTH")     'Sheet PLHD_GPE
        .Range("D10").value = "Thu" & ChrW(7871) & " VAT (" & Thue_VAT * 100 & "%)"
        'End Ktra
        j = .Cells(Rows.count, "G").End(xlUp).Row
        If j > 11 Then
            'Xoa toan bo bang du lieu hien huu dang co
            .Rows("11:" & j - 1).Delete Shift:=xlShiftUp
        Else
            .Range("A11:F" & j - 1).ClearContents
        End If
        .Range("A11:A" & 11 + k).EntireRow.Insert
        If k > 0 Then
            .Range("A11").Resize(k, 6).value = res_DN
        End If
        j = .Cells(Rows.count, "G").End(xlUp).Row
        .Range("B" & j).value = "T" & ChrW(7892) & "NG C" & ChrW(7896) & "NG"
        .Range("C" & j).Formula = "=SUBTOTAL(9,C10:C" & j - 1 & ")"
        .Range("D" & j).Formula = "=SUBTOTAL(9,D10:D" & j - 1 & ")"
        .Range("E" & j).Formula = "=SUBTOTAL(9,E10:E" & j - 1 & ")"
        '        .Range("A" & j + 1).value = DocSoUni(.Range("H" & j))
        .Range("C11:I" & j).NumberFormat = "#,##0"
        .Range("B11:B" & j).WrapText = 1
        .Range("B11:B" & j).HorizontalAlignment = xlJustify
        .Range("A11:F" & j).Font.Bold = False
        .Range("A" & j & ":I" & j).Font.Bold = True
        .Range("A11:F" & j).Borders.LineStyle = 1
        .PageSetup.PrintArea = "$A$1:$F" & j + 4 & ""
    End With
End Sub

Đây là code VB.Net

Mã:
   Sub Run_THop_GtrPO()

        Dim sh_PLHD As Excel.Worksheet = Globals.ThisAddIn.GetWorksheet("PO_PLHD")
        Dim arr As Object(,) = sh_PLHD.Range("A9:K" & sh_PLHD.Range("D" & sh_PLHD.Rows.Count).End(XlDirection.xlUp).Row).Value
        Dim sRow As Integer = arr.GetUpperBound(0)

        Dim Thue_VAT As Double = ReadRegistryValue(HKEY_SET_HC, "Thue_VAT") / 100
        Dim res_DN As Object(,)
        'ReDim Preserve res_DN(sRow + 1, 5)
        ReDim res_DN(0 To sRow, 0 To 6)
        Dim k As Integer = 0
        For i As Integer = 1 To sRow
            If arr(i, 1).ToString() = "HM" Then
                k += 1

                res_DN(k, 0) = k
                res_DN(k, 1) = arr(i, 3)
                'Don gia truoc thue
                res_DN(k, 2) = Math.Round(arr(i, 10) / (1 + Thue_VAT), 1)
                'Thue VAT
                res_DN(k, 3) = Math.Round((arr(i, 10) / (1 + Thue_VAT)) * Thue_VAT, 1)
                'Tong cong
                res_DN(k, 4) = res_DN(k, 2) + res_DN(k, 3)
                MsgBox("Có HM thứ: " & k & "tại dòng " & i & "và có giá trị: " & res_DN(k, 4))
            End If

        Next i

        Dim sh_BTH As Excel.Worksheet = Globals.ThisAddIn.GetWorksheet("PO-BTH")
        sh_BTH.Select()

        With sh_BTH
            .Range("D10").Value = "Thuế VAT (" & Thue_VAT * 100 & "%)"
            'End Ktra
            Dim j As Integer = Globals.ThisAddIn.GetLastRowInSheet(sh_BTH, "G")
            MsgBox(j)
            If j > 11 Then
                'Xoa toan bo bang du lieu hien huu dang co
                .Rows("11:" & j - 1).Delete(Shift:=XlDeleteShiftDirection.xlShiftUp)
            Else
                .Range("A11:F" & j - 1).ClearContents()
            End If
            .Range("A11:A" & 11 + k).EntireRow.Insert()
            If k > 0 Then
                .Range("A11").Resize(k, 6).Value = res_DN
            End If
            j = Globals.ThisAddIn.GetLastRowInSheet(sh_BTH, "G")

            .Range("B" & j).Value = "TỔNG CỘNG"
            .Range("C" & j).Formula = "=SUBTOTAL(9,C10:C" & j - 1 & ")"
            .Range("D" & j).Formula = "=SUBTOTAL(9,D10:D" & j - 1 & ")"
            .Range("E" & j).Formula = "=SUBTOTAL(9,E10:E" & j - 1 & ")"
            .Range("C11:I" & j).NumberFormat = "#,##0"
            .Range("B11:B" & j).WrapText = 1
            '.Range("B11:B" & j).HorizontalAlignment = xlJustify
            .Range("A11:F" & j).Font.Bold = False
            .Range("A" & j & ":I" & j).Font.Bold = True
            .Range("A11:F" & j).Borders.LineStyle = 1
            .PageSetup.PrintArea = "$A$1:$F" & j + 4 & ""

        End With

    End Sub
Kết quả khi chạy code VB.net
1677990469563.png
 

File đính kèm

  • Help Code.xlsx
    18.2 KB · Đọc: 0
Tôi có code đang dùng cho VBA chạy rất tốt và đúng yêu cầu, tuy nhiên khi chuyển sang vb.net code chỉ xuất được giá trị đầu tiên của mảng không biết lỗi ở đâu mong anh chị quen vb.net chỉ giúp
Dữ liệu ban đầu
View attachment 287199
Dữ liệu mong muốn xuất ra (Code VBA chạy tốt)
View attachment 287200

Đây là code VBA của tôi
Mã:
Sub Run_THop_GtrPO()
    'Add 25/06/2022: Bo sung tong hop tham dinh ra Sheet Tong hop
    Dim arr_DN(), iR1&, res_DN()
    Set sh_PLPO = Sheets("PO_PLHD")     'Sheet Tham Dinh Quyet toan
    Sheets("PO-BTH").Select
    Thue_VAT = GetRegistry(HKEY_SET_HC, "Thue_VAT") / 100
    'MsgBox sh_TH_DNghiQT.Range("C" & sh_TH_DNghiQT.Rows.count).End(xlUp).row
    arr_DN = sh_PLPO.Range("A9:K" & sh_PLPO.Range("D" & sh_PLPO.Rows.count).End(xlUp).Row).value
    sRow = UBound(arr_DN)
    ReDim res_DN(1 To sRow, 1 To 6)
    For i = 1 To sRow
        If arr_DN(i, 1) = "HM" Then
            k = k + 1
            res_DN(k, 1) = k
            res_DN(k, 2) = arr_DN(i, 3)
            'Don gia truoc thue
            res_DN(k, 3) = Round(arr_DN(i, 10) / (1 + Thue_VAT), 1)
            'Thue VAT
            res_DN(k, 4) = Round((arr_DN(i, 10) / (1 + Thue_VAT)) * Thue_VAT, 1)
            'Tong cong
            res_DN(k, 5) = res_DN(k, 3) + res_DN(k, 4)
        End If
    Next i
    With Sheets("PO-BTH")     'Sheet PLHD_GPE
        .Range("D10").value = "Thu" & ChrW(7871) & " VAT (" & Thue_VAT * 100 & "%)"
        'End Ktra
        j = .Cells(Rows.count, "G").End(xlUp).Row
        If j > 11 Then
            'Xoa toan bo bang du lieu hien huu dang co
            .Rows("11:" & j - 1).Delete Shift:=xlShiftUp
        Else
            .Range("A11:F" & j - 1).ClearContents
        End If
        .Range("A11:A" & 11 + k).EntireRow.Insert
        If k > 0 Then
            .Range("A11").Resize(k, 6).value = res_DN
        End If
        j = .Cells(Rows.count, "G").End(xlUp).Row
        .Range("B" & j).value = "T" & ChrW(7892) & "NG C" & ChrW(7896) & "NG"
        .Range("C" & j).Formula = "=SUBTOTAL(9,C10:C" & j - 1 & ")"
        .Range("D" & j).Formula = "=SUBTOTAL(9,D10:D" & j - 1 & ")"
        .Range("E" & j).Formula = "=SUBTOTAL(9,E10:E" & j - 1 & ")"
        '        .Range("A" & j + 1).value = DocSoUni(.Range("H" & j))
        .Range("C11:I" & j).NumberFormat = "#,##0"
        .Range("B11:B" & j).WrapText = 1
        .Range("B11:B" & j).HorizontalAlignment = xlJustify
        .Range("A11:F" & j).Font.Bold = False
        .Range("A" & j & ":I" & j).Font.Bold = True
        .Range("A11:F" & j).Borders.LineStyle = 1
        .PageSetup.PrintArea = "$A$1:$F" & j + 4 & ""
    End With
End Sub

Đây là code VB.Net

Mã:
   Sub Run_THop_GtrPO()

        Dim sh_PLHD As Excel.Worksheet = Globals.ThisAddIn.GetWorksheet("PO_PLHD")
        Dim arr As Object(,) = sh_PLHD.Range("A9:K" & sh_PLHD.Range("D" & sh_PLHD.Rows.Count).End(XlDirection.xlUp).Row).Value
        Dim sRow As Integer = arr.GetUpperBound(0)

        Dim Thue_VAT As Double = ReadRegistryValue(HKEY_SET_HC, "Thue_VAT") / 100
        Dim res_DN As Object(,)
        'ReDim Preserve res_DN(sRow + 1, 5)
        ReDim res_DN(0 To sRow, 0 To 6)
        Dim k As Integer = 0
        For i As Integer = 1 To sRow
            If arr(i, 1).ToString() = "HM" Then
                k += 1

                res_DN(k, 0) = k
                res_DN(k, 1) = arr(i, 3)
                'Don gia truoc thue
                res_DN(k, 2) = Math.Round(arr(i, 10) / (1 + Thue_VAT), 1)
                'Thue VAT
                res_DN(k, 3) = Math.Round((arr(i, 10) / (1 + Thue_VAT)) * Thue_VAT, 1)
                'Tong cong
                res_DN(k, 4) = res_DN(k, 2) + res_DN(k, 3)
                MsgBox("Có HM thứ: " & k & "tại dòng " & i & "và có giá trị: " & res_DN(k, 4))
            End If

        Next i

        Dim sh_BTH As Excel.Worksheet = Globals.ThisAddIn.GetWorksheet("PO-BTH")
        sh_BTH.Select()

        With sh_BTH
            .Range("D10").Value = "Thuế VAT (" & Thue_VAT * 100 & "%)"
            'End Ktra
            Dim j As Integer = Globals.ThisAddIn.GetLastRowInSheet(sh_BTH, "G")
            MsgBox(j)
            If j > 11 Then
                'Xoa toan bo bang du lieu hien huu dang co
                .Rows("11:" & j - 1).Delete(Shift:=XlDeleteShiftDirection.xlShiftUp)
            Else
                .Range("A11:F" & j - 1).ClearContents()
            End If
            .Range("A11:A" & 11 + k).EntireRow.Insert()
            If k > 0 Then
                .Range("A11").Resize(k, 6).Value = res_DN
            End If
            j = Globals.ThisAddIn.GetLastRowInSheet(sh_BTH, "G")

            .Range("B" & j).Value = "TỔNG CỘNG"
            .Range("C" & j).Formula = "=SUBTOTAL(9,C10:C" & j - 1 & ")"
            .Range("D" & j).Formula = "=SUBTOTAL(9,D10:D" & j - 1 & ")"
            .Range("E" & j).Formula = "=SUBTOTAL(9,E10:E" & j - 1 & ")"
            .Range("C11:I" & j).NumberFormat = "#,##0"
            .Range("B11:B" & j).WrapText = 1
            '.Range("B11:B" & j).HorizontalAlignment = xlJustify
            .Range("A11:F" & j).Font.Bold = False
            .Range("A" & j & ":I" & j).Font.Bold = True
            .Range("A11:F" & j).Borders.LineStyle = 1
            .PageSetup.PrintArea = "$A$1:$F" & j + 4 & ""

        End With

    End Sub
Kết quả khi chạy code VB.net
View attachment 287201
Bạn debug chạy step by step thì biết sai chỗ nào thôi chứ khó gì.
 
Dạ em thử hết rồi ạ, kết quả luuon thiếu mục cuối cùng không rõ nguyên nhân ạ
Đoạn code này em test báo đúng số lượng MsgBox("Có HM thứ: " & k & "tại dòng " & i & "và có giá trị: " & res_DN(k, 4)) nhưng khi xuất ra Sheet lại thiếu
 
Dạ em thử hết rồi ạ, kết quả luuon thiếu mục cuối cùng không rõ nguyên nhân ạ
Đoạn code này em test báo đúng số lượng MsgBox("Có HM thứ: " & k & "tại dòng " & i & "và có giá trị: " & res_DN(k, 4)) nhưng khi xuất ra Sheet lại thiếu
Mảng trong vb.net luôn chạy từ 0 mà bạn lại gán vào từ lúc k = 1 thế.
 
Dạ em khai báo Dim k As Integer = 0 ngay từ đầu mà
chắc là do ngay từ đầu vòng lặp bạn đã tăng k lên thành 1 rồi, nên khi trả kết quả mảng nó chạy từ 0 trong khi đến phần từ (1,0) của bạn mới bắt đầu có dữ liệu
 
Hix em không rõ nguyên nhân nữa, các anh chỉ giúp ạ
 
Hix em không rõ nguyên nhân nữa, các anh chỉ giúp ạ
Giờ bạn debug lại, đến chỗ gán giá trị cho mảng thì debug từng bước một, mỗi lần debug thì xem lại giá trị mà mảng được gán và giá trị biến chạy là tìm ra thôi, chứ giờ chỉ có mỗi code không ngồi hình dung ra nó hơi khó
 
Em sửa chỗ này thì kết quả ra đúng, không hiểu bản chất khai báo hay nhầm lẫn kiểu gì nữa ạ
Mã:
            If k > 0 Then
                .Range("A11").Resize(k + 1, 5).Value = res_DN
            End If
 
Em sửa chỗ này thì kết quả ra đúng, không hiểu bản chất khai báo hay nhầm lẫn kiểu gì nữa ạ
Mã:
            If k > 0 Then
                .Range("A11").Resize(k + 1, 5).Value = res_DN
            End If
Bạn gán dòng đầu tiên lúc k = 1 (mà lẽ ra lúc đó k phải bằng 0) và sau khi bạn chép xuống sheet mà resize k thì nó có k dòng nhưng dòng đầu là trống hoàn toàn, dòng cuối thì không được chép ra
 
Nếu dùng k làm số đếm thì khởi đầu nó bằng
k = 0
For...
Lúc chép mảng lại vào sheet thì xét
If k then...
Tuy nhiên, đây là thói quen lười biếng của trường phái GPE. Đối với người biết code của mình thì được, nhưng gặp người lạ thì rất dễ bị sai.

Cách đúng đắn là phải xét cái LBound của mảng. Và dùng k làm chỉ số
k = Lbound(mang) - 1
For ...
Lúc chép mảng vào lại sheet thì:
If k >= LBound(mang) Then range("gì gì đó").Resize(k - LBound(mang) + 1).Value = mang
(nếu k là chỉ số phần tử cuối của mảng thì số phần tử = k - chỉ số phần tử đầu tiên + 1)
 
Web KT
Back
Top Bottom