Các câu hỏi về mảng trong VBA (Array)

Liên hệ QC

viehoai

Thành viên gắn bó
Tham gia
22/5/09
Bài viết
2,599
Được thích
2,908
Xin các anh chị giúp đỡ Code Gán các giá trị của một Range là các phần tử của Mãng
Ví dụ: Tôi có các giá trị của Range("A1:A10"). Tôi muốn viết code để gán giá trị của các cells từ A1:A10 là các phần tử của Mãng Arr chẳn hạn.
Xin cảm ơn các anh chị
 
Bạn tạo 1 mảng sArr gồm 10 cột (ứng với 10 dòng) với số dòng là hoán vị cao nhất( hình như là 36)
Chạy từng dòng lấy hoán vị 3 số thỏa mãn tổng như bạn đã làm và gán vào từng cột tương ứng, dòng 1 gán cột 1, dòng 2 gán cột 2. Để nhẹ bộ nhớ có thể chỉ gán số thứ tự
Dùng Function để lấy các mảng các tổ hợp của 10 dòng
Mang = CreateToHop( sArr , True)
Mỗi dòng của mảng là 1 phương án
Hy vọng máy tính đủ bộ nhớ
Mã:
Function CreateToHop(ByVal sArr As Variant, Optional ByVal bNotBlank = False) As Variant
'CreateToHop: Liet ke to hop N phan tu cua "Mang" 2 chieu "sArr"
'sArr: Là Array hoac Range, neu khac se tra ve "Empty"
'bNotBlank: Là giá tri luan ly, mac dinh = False lay ca gia tri "Empty"
'bNotBlank = True: Loai bo gia tri "Empty", neu có Cot chi co gia tri "Empty", Function tra ve "Empty"
  Dim aRow(), Res(), sCol&, sRow&, N As Double, i As Double, j&, iR&, tmp

  On Error Resume Next
  If TypeName(sArr) = "Range" Then
    If sArr.Count = 1 Then
      tmp = sArr.Value
      ReDim sArr(1 To 1, 1 To 1)
      sArr(1, 1) = tmp
    Else
      sArr = sArr.Value
    End If
  End If
  sRow = UBound(sArr, 1):   sCol = UBound(sArr, 2)
  If Err.Number > 0 Then Exit Function

  Call AddValue_aRow(sArr, aRow, sRow, sCol, bNotBlank)
  N = aRow(1)
  If N = 0 Then Exit Function
  ReDim Res(1 To N, 1 To sCol)
  For i = 1 To N
    For j = 1 To sCol
      iR = ((i - 1) Mod aRow(j)) \ aRow(j + 1) + 1 'Thu tu dong du lieu
      If sArr(iR, j) = Empty Then Res(i, j) = "" Else Res(i, j) = sArr(iR, j)
    Next j
  Next i
  CreateToHop = Res
End Function

Private Sub AddValue_aRow(sArr, aRow, sRow, sCol, bNotBlank)
  Dim i&, j&, k&, tmp
  ReDim aRow(1 To sCol + 1)
  aRow(sCol + 1) = 1
  If bNotBlank = False Then
    For j = sCol To 1 Step -1
      aRow(j) = sRow * aRow(j + 1)
    Next j
  Else
    For j = sCol To 1 Step -1
      k = 0
      For i = 1 To sRow
        tmp = sArr(i, j)
        If Len(tmp) Then
          sArr(i, j) = Empty
          k = k + 1
          sArr(k, j) = tmp
        End If
      Next i
      If k > 0 Then aRow(j) = k * aRow(j + 1)
    Next j
  End If
End Sub
Đây là chương trình mình viết trong Visual Studio
vẫn với yêu cầu TongKg mỗi cột không quá 25 và TongM3 mỗi cột không quá 2.8 (như bài trên)
nhưng đang mắc ở Sub TestCol_KetQua() chưa lập được TỔ HỢP CÁC NGHIỆM để tìm ra nghiệm 3 cột có giá trị trong mỗi cột >0 là ít nhất thế nào?

Mã:
Module Module1
    Public SoBo As Integer ' n là số bó cần phân tích thành tổng
    Public w, SoLuongCont, CountColHV, iColHV As Integer ' w là số đếm các giá trị của mảng giá trị có tổng là số bó, chưa hóan vị
    Public PhanTichTong, y ' Mảng các giá trị có tổng là số bó, chưa hoán vị
    Public StringNum As String
    Public st As Stopwatch
    Public countTamHV As Integer
    Public cDanhDauHoanVi, xHV, ArrTamHV, Dic, DicBo
    Dim tRow(9, 1)

    Public HoanViTong, ColHoanVi

    Public aSo() As Byte
    Public tTong() As Integer
    Public exam(9)
    Sub Main()
        '------Chương trình Phân tích Tổng- Start------
        st = New Stopwatch
        tRow(0, 0) = 1.46 : tRow(0, 1) = 0.12
        tRow(1, 0) = 1.46 : tRow(1, 1) = 0.16
        tRow(2, 0) = 1.33 : tRow(2, 1) = 0.18
        tRow(3, 0) = 1.5 : tRow(3, 1) = 0.16
        tRow(4, 0) = 1.46 : tRow(4, 1) = 0.2
        tRow(5, 0) = 1.93 : tRow(5, 1) = 0.2
        tRow(6, 0) = 1.54 : tRow(6, 1) = 0.16
        tRow(7, 0) = 0.87 : tRow(7, 1) = 0.16
        tRow(8, 0) = 1.74 : tRow(8, 1) = 0.12
        tRow(9, 0) = 1.03 : tRow(9, 1) = 0.16

        exam(0) = 7
        exam(1) = 5
        exam(2) = 5
        exam(3) = 4
        exam(4) = 5
        exam(5) = 5
        exam(6) = 5
        exam(7) = 7
        exam(8) = 5
        exam(9) = 4


        SoLuongCont = 3
        'SoBo = 41
        st.Start()
        DicBo = CreateObject("Scripting.Dictionary")
        DicBo.CompareMode = vbTextCompare
        For thu = 0 To 9
            SoBo = exam(thu)
            If Not DicBo.Exists(SoBo) Then
                Call Phantich()
                iColHV += 1
                DicBo(SoBo) = ColHoanVi(iColHV - 1)
            Else
                CountColHV += 1
                ReDim Preserve ColHoanVi(CountColHV - 1)
                ColHoanVi(CountColHV - 1) = DicBo(SoBo)
            End If
        Next
        DicBo.RemoveAll
        'Console.WriteLine("Nhap vao so So Bo")
        'SoBo = Console.ReadLine
        'Console.WriteLine("Nhap vao So Luong Cont")
        'SoLuongCont = Console.ReadLine

        TestCol_KetQua()
        st.Stop()
        Console.WriteLine(st.Elapsed)
        Console.ReadKey()
    End Sub
    Sub Phantich()
        Dic = CreateObject("Scripting.Dictionary")
        Dic.CompareMode = vbTextCompare

        ReDim aSo(SoBo)
        ReDim tTong(SoBo)
        aSo(0) = 1
        LuiPT(1)
        CountColHV += 1
        ReDim Preserve ColHoanVi(CountColHV - 1)
        ColHoanVi(CountColHV - 1) = HoanViTong

        Dic.RemoveAll
        Erase aSo, tTong
        countTamHV = Nothing
        y = Nothing
        StringNum = Nothing
        cDanhDauHoanVi = Nothing
        xHV = Nothing
        ArrTamHV = Nothing
        HoanViTong = Nothing
    End Sub
    Sub LuiPT(xPT As Short)
        For z = aSo(xPT - 1) To (SoBo - tTong(xPT - 1)) / 2
            aSo(xPT) = z
            tTong(xPT) = tTong(xPT - 1) + z
            LuiPT(xPT + 1)
        Next
        aSo(xPT) = SoBo - tTong(xPT - 1)
        If xPT = SoLuongCont Then
            ReDim y(SoLuongCont - 1)
            For k = 1 To xPT - 1
                y(k - 1) = aSo(k)
            Next
            y(xPT - 1) = aSo(xPT)
            Call HoanVi()
        ElseIf xPT < SoLuongCont Then
            ReDim y(SoLuongCont - 1)
            For k = 1 To xPT - 1
                y(k - 1) = aSo(k)
            Next
            y(xPT - 1) = aSo(xPT)
            For iBosung = xPT To SoLuongCont - 1
                y(iBosung) = 0
            Next
            Call HoanVi()
        End If
    End Sub
    '------Chương trình Phân tích Tổng- End------
    '------Chương trình Hoán Vị - Start------
    Sub HoanVi()
        ReDim cDanhDauHoanVi(SoLuongCont - 1)
        ReDim xHV(SoLuongCont - 1)
        For vHV = 0 To SoLuongCont - 1
            cDanhDauHoanVi(vHV) = True
        Next
        LuiHoanVi(0)
    End Sub
    Sub LuiHoanVi(iHV As Short)
        StringNum = vbNullString
        For uHV = 0 To SoLuongCont - 1
            If cDanhDauHoanVi(uHV) Then
                xHV(iHV) = uHV
                'Neu i= k thi in ra ket qua
                If iHV = SoLuongCont - 1 Then
                    ReDim ArrTamHV(SoLuongCont - 1)
                    For vHV = 0 To SoLuongCont - 1 ' Thiết lập chuỗi Key
                        StringNum += Str(y(xHV(vHV))) ' xHV(v) chỉ số 0,1,2,3,4
                    Next
                    If Not Dic.exists(StringNum) Then
                        Dic(StringNum) = StringNum
                        For vHV = 0 To SoLuongCont - 1 ' in ra chuoi Hoan Vi
                            ArrTamHV(vHV) = y(xHV(vHV)) ' xHV(v) chỉ số 0,1,2,3,4
                        Next
                        countTamHV += 1
                        ReDim Preserve HoanViTong(countTamHV - 1)
                        HoanViTong(countTamHV - 1) = ArrTamHV
                    End If
                Else
                        cDanhDauHoanVi(uHV) = False
                    LuiHoanVi(iHV + 1)
                    cDanhDauHoanVi(uHV) = True
                End If
            End If
        Next
    End Sub
 
Upvote 0
Đây là chương trình mình viết trong Visual Studio
vẫn với yêu cầu TongKg mỗi cột không quá 25 và TongM3 mỗi cột không quá 2.8 (như bài trên)
nhưng đang mắc ở Sub TestCol_KetQua() chưa lập được TỔ HỢP CÁC NGHIỆM để tìm ra nghiệm 3 cột có giá trị trong mỗi cột >0 là ít nhất thế nào?

Mã:
Module Module1
    Public SoBo As Integer ' n là số bó cần phân tích thành tổng
    Public w, SoLuongCont, CountColHV, iColHV As Integer ' w là số đếm các giá trị của mảng giá trị có tổng là số bó, chưa hóan vị
    Public PhanTichTong, y ' Mảng các giá trị có tổng là số bó, chưa hoán vị
    Public StringNum As String
    Public st As Stopwatch
    Public countTamHV As Integer
    Public cDanhDauHoanVi, xHV, ArrTamHV, Dic, DicBo
    Dim tRow(9, 1)

    Public HoanViTong, ColHoanVi

    Public aSo() As Byte
    Public tTong() As Integer
    Public exam(9)
    Sub Main()
        '------Chương trình Phân tích Tổng- Start------
        st = New Stopwatch
        tRow(0, 0) = 1.46 : tRow(0, 1) = 0.12
        tRow(1, 0) = 1.46 : tRow(1, 1) = 0.16
        tRow(2, 0) = 1.33 : tRow(2, 1) = 0.18
        tRow(3, 0) = 1.5 : tRow(3, 1) = 0.16
        tRow(4, 0) = 1.46 : tRow(4, 1) = 0.2
        tRow(5, 0) = 1.93 : tRow(5, 1) = 0.2
        tRow(6, 0) = 1.54 : tRow(6, 1) = 0.16
        tRow(7, 0) = 0.87 : tRow(7, 1) = 0.16
        tRow(8, 0) = 1.74 : tRow(8, 1) = 0.12
        tRow(9, 0) = 1.03 : tRow(9, 1) = 0.16

        exam(0) = 7
        exam(1) = 5
        exam(2) = 5
        exam(3) = 4
        exam(4) = 5
        exam(5) = 5
        exam(6) = 5
        exam(7) = 7
        exam(8) = 5
        exam(9) = 4


        SoLuongCont = 3
        'SoBo = 41
        st.Start()
        DicBo = CreateObject("Scripting.Dictionary")
        DicBo.CompareMode = vbTextCompare
        For thu = 0 To 9
            SoBo = exam(thu)
            If Not DicBo.Exists(SoBo) Then
                Call Phantich()
                iColHV += 1
                DicBo(SoBo) = ColHoanVi(iColHV - 1)
            Else
                CountColHV += 1
                ReDim Preserve ColHoanVi(CountColHV - 1)
                ColHoanVi(CountColHV - 1) = DicBo(SoBo)
            End If
        Next
        DicBo.RemoveAll
        'Console.WriteLine("Nhap vao so So Bo")
        'SoBo = Console.ReadLine
        'Console.WriteLine("Nhap vao So Luong Cont")
        'SoLuongCont = Console.ReadLine

        TestCol_KetQua()
        st.Stop()
        Console.WriteLine(st.Elapsed)
        Console.ReadKey()
    End Sub
    Sub Phantich()
        Dic = CreateObject("Scripting.Dictionary")
        Dic.CompareMode = vbTextCompare

        ReDim aSo(SoBo)
        ReDim tTong(SoBo)
        aSo(0) = 1
        LuiPT(1)
        CountColHV += 1
        ReDim Preserve ColHoanVi(CountColHV - 1)
        ColHoanVi(CountColHV - 1) = HoanViTong

        Dic.RemoveAll
        Erase aSo, tTong
        countTamHV = Nothing
        y = Nothing
        StringNum = Nothing
        cDanhDauHoanVi = Nothing
        xHV = Nothing
        ArrTamHV = Nothing
        HoanViTong = Nothing
    End Sub
    Sub LuiPT(xPT As Short)
        For z = aSo(xPT - 1) To (SoBo - tTong(xPT - 1)) / 2
            aSo(xPT) = z
            tTong(xPT) = tTong(xPT - 1) + z
            LuiPT(xPT + 1)
        Next
        aSo(xPT) = SoBo - tTong(xPT - 1)
        If xPT = SoLuongCont Then
            ReDim y(SoLuongCont - 1)
            For k = 1 To xPT - 1
                y(k - 1) = aSo(k)
            Next
            y(xPT - 1) = aSo(xPT)
            Call HoanVi()
        ElseIf xPT < SoLuongCont Then
            ReDim y(SoLuongCont - 1)
            For k = 1 To xPT - 1
                y(k - 1) = aSo(k)
            Next
            y(xPT - 1) = aSo(xPT)
            For iBosung = xPT To SoLuongCont - 1
                y(iBosung) = 0
            Next
            Call HoanVi()
        End If
    End Sub
    '------Chương trình Phân tích Tổng- End------
    '------Chương trình Hoán Vị - Start------
    Sub HoanVi()
        ReDim cDanhDauHoanVi(SoLuongCont - 1)
        ReDim xHV(SoLuongCont - 1)
        For vHV = 0 To SoLuongCont - 1
            cDanhDauHoanVi(vHV) = True
        Next
        LuiHoanVi(0)
    End Sub
    Sub LuiHoanVi(iHV As Short)
        StringNum = vbNullString
        For uHV = 0 To SoLuongCont - 1
            If cDanhDauHoanVi(uHV) Then
                xHV(iHV) = uHV
                'Neu i= k thi in ra ket qua
                If iHV = SoLuongCont - 1 Then
                    ReDim ArrTamHV(SoLuongCont - 1)
                    For vHV = 0 To SoLuongCont - 1 ' Thiết lập chuỗi Key
                        StringNum += Str(y(xHV(vHV))) ' xHV(v) chỉ số 0,1,2,3,4
                    Next
                    If Not Dic.exists(StringNum) Then
                        Dic(StringNum) = StringNum
                        For vHV = 0 To SoLuongCont - 1 ' in ra chuoi Hoan Vi
                            ArrTamHV(vHV) = y(xHV(vHV)) ' xHV(v) chỉ số 0,1,2,3,4
                        Next
                        countTamHV += 1
                        ReDim Preserve HoanViTong(countTamHV - 1)
                        HoanViTong(countTamHV - 1) = ArrTamHV
                    End If
                Else
                        cDanhDauHoanVi(uHV) = False
                    LuiHoanVi(iHV + 1)
                    cDanhDauHoanVi(uHV) = True
                End If
            End If
        Next
    End Sub
Số khả năng quá lớn có tới 14 chữ số, mình không có thời gian chạy thử 10 dòng, chỉ chạy thử với 8 dòng dữ liệu, thêm dòng dữ liệu thời gian tăng lên hơn cấp số nhân
Nếu số khả năng tăng lên vượt quá 15 chữ số, sub sẽ tiêu vì giới hạn tính toán số trong VBA
Nếu bỏ công sức tách code thành các sub nhỏ tìm theo số thứ tự từ thấp đến cao của số giá trị >0 có thể rút ngắn thời gian
Mã:
Sub XYZ()
  Dim aMT_CBM(), aSL(), aGHan
  Dim Dic As Object, ToHop, ikey
  Dim sRow&, i&
  Const sCol As Long = 3
  aGHan = Array(0, 25, 2.8) 'Gioi Han dieu kien
  aMT_CBM = Range("B4:C11").Value
  aSL = Range("E4:E11").Value
  sRow = UBound(aSL)
  ReDim Res(1 To sRow, 1 To 3) 'Ket qua
  Set Dic = CreateObject("scripting.dictionary")
  For i = 1 To sRow 'Tao To Hop tung gia tri So Luong
    ikey = aSL(i, 1)
    If Dic.exists(ikey) = False Then
      Call CreateToHopSoLuong(ToHop, sCol, ikey)
      Dic.Add ikey, ToHop
    End If
  Next i
  Call KetQua(Dic, aMT_CBM, aSL, aGHan, sRow, sCol)
End Sub

Private Sub KetQua(Dic, aMT_CBM, aSL, aGHan, sRow, sCol)
  Dim ToHop, aRow(), aDKien(), Res()
  Dim i&, j&, iR&, q As Double, N As Double, t As Double, iMin&, dem&
  ReDim aRow(1 To sRow + 1) 'Tao mang xac dinh thu tu dong
  aRow(sRow + 1) = 1
  For i = sRow To 1 Step -1
    aRow(i) = UBound(Dic.Item(aSL(i, 1))) * aRow(i + 1)
  Next i
  N = aRow(1) 'So kha nang
  iMin = sRow * sCol + 1
  For q = 1 To N
    dem = 0
    ReDim Res(1 To sRow, 1 To sCol)
    ReDim aDKien(1 To 2, 1 To sCol) 'Mang xet dieu kien
    For i = 1 To sRow
      t = q - 1
      Do While t >= aRow(i)
        t = t - aRow(i)
      Loop
      iR = Int(t / aRow(i + 1)) + 1
      ToHop = Dic.Item(aSL(i, 1))
      For j = 1 To sCol
        Res(i, j) = ToHop(iR, j)
        For m = 1 To 2
          aDKien(m, j) = aDKien(m, j) + Res(i, j) * aMT_CBM(i, m)
          If aDKien(m, j) > aGHan(m) Then GoTo TroLai
        Next m
      Next j
      dem = dem + ToHop(iR, sCol + 1)
    Next i
    If iMin > dem Then
      Range("F4").Resize(sRow, sCol) = Res
      iMin = dem
      If iMin = sRow Then Exit Sub
    End If
TroLai:
  Next q
End Sub

Private Sub CreateToHopSoLuong(ToHop, sCol, ByVal SL As Long)
  Dim sArr(), aRow(), tmp(), i&, j&, q&, iR&, N&, tong&
  ReDim aRow(1 To sCol)  'Tao mang xac dinh thu tu dong
  aRow(sCol) = 1
  For j = sCol - 1 To 1 Step -1
    aRow(j) = (SL + 1) * aRow(j + 1)
  Next j
  N = aRow(1)
  ReDim sArr(1 To N, 1 To sCol + 1)
  For i = 1 To N
    tong = 0
    ReDim tmp(1 To sCol)
    For j = 1 To sCol - 1
      iR = ((i - 1) Mod aRow(j)) \ aRow(j + 1)
      tong = tong + iR
      If tong > SL Then Exit For
      tmp(j) = iR
      If iR > 0 Then tmp(sCol) = tmp(sCol) + 1 ' so gia tri ket qua >0
    Next j
    If j = sCol Then
      k = k + 1
      For q = 1 To sCol - 1
        sArr(k, q) = tmp(q)
      Next q
      sArr(k, sCol) = SL - tong
      If sArr(k, sCol) > 0 Then tmp(sCol) = tmp(sCol) + 1 ' so gia tri ket qua >0
      sArr(k, sCol + 1) = tmp(sCol) ' so gia tri ket qua >0
    End If
  Next i
  ReDim ToHop(1 To k, 1 To sCol + 1) 'Tao mang ToHop
  For i = 1 To k
    For j = 1 To sCol + 1
      ToHop(i, j) = sArr(i, j)
    Next j
  Next i
  Erase sArr: Erase aRow: Erase tmp
End Sub
 
Upvote 0
Em nhờ các bác giúp 4 trường hợp sau giúp:


1/ Code VBA để coppy sau VD: Sheet 1
Khi ta dang Mở File C ở Sheet 1 có 1 nút "coppy" Khi click vào Nút "Coppy" thì Coppy tất cả các hàng trong Sheet1 File A những cột A,B,C,D Nếu thỏa cột B có chữ "nhà xe" vào Sheet1 File C


2/ Code VBA để coppy sau VD: Sheet 2
Khi ta dang Mở Sheet2 File C ở Sheet 2 có 1 nút "coppy" Khi click vào Nút "Coppy" thì Coppy tất cả các hàng trong Sheet2 File A những cột A,B,C,D,E,F,G,H,I,K Nếu thỏa cột C Không có chữ "HQ" vào Sheet2 File C

3/ Code VBA để coppy sau VD: Sheet 3
Khi dang lam viec o Sheet3 FileA có các hàng dữ liệu liền nhau có các cột A,B,C,D,E và trong sheet đó có nút Coppy. Nếu Click vào nút Coppy mà thỏa mãn 2 điều kiện sau:
- Dieu kien 1: cột A trong Sheet3 FileC và cột A Sheet3 FileA (sheet và file hiện thời làm việc) có số số liệu trùng nhau.
- Dieu kien 2: cột F trong Sheet3 FileC không có dấu "x"
thì sẽ coppy các dữ liệu của các hàng ở Cột C,D,E của Sheet3 FileC sang các cột C,D,E của Sheet3 FileA
(lưu ý giúp: dữ liệu hãng ở Sheet3 FileA có thể ko liền nhau)

4/ VD: Sheet 4
Trong 1 Form có 2 text boxt sau:
Text boxt 1, Text boxt 2
Khi nhập dữ liệu vào Text boxt 1 bấm enter thì Text boxt 2 ktra 3 ký tự đầu của
Text boxt 1 nếu có 3 chữ "kle" thì Text boxt 2 sẽ tự điền là "kh" còn ko có Text boxt 2 sẽ điền "nhà xe"
 

File đính kèm

  • FileA.xlsx
    55.6 KB · Đọc: 1
  • FileC.xlsx
    12.8 KB · Đọc: 0
Upvote 0
Nhờ anh/chị thông não cá vàng giúp em :D
Giả sử, em có mảng 2 chiều Array(1 to 15, 1 to 6)
Giờ em muốn gán các giá trị Array(10 to 15, 1 to 6) xuống SheetForm không dùng vòng lặp bằng cách nào ạ?
 
Upvote 0
SheetForm là cái gì? và giá trị Array(10 to 15, 1 to 6) là gì?
Nếu nó là Sheet, không phải là Form, và muốn gán mảng từ dòng 10 đến dòng 15 thì có 2 cách:
Cách 1
1. Tạm gán cả mảng xuống một vùng nào đó trống trải trên sheet
2. Copy kể từ dòng 10 của vùng này vào 1 array khác
3. Gán array mới vào đúng nơi mong muốn
4. Delete vùng tạm
Cách 2
1. Gán cả mảng vào nơi mong muốn
2. Delete 9 dòng đầu
 
Upvote 0
SheetForm là cái gì? và giá trị Array(10 to 15, 1 to 6) là gì?
Nếu nó là Sheet, không phải là Form, và muốn gán mảng từ dòng 10 đến dòng 15 thì có 2 cách:
Cách 1
1. Tạm gán cả mảng xuống một vùng nào đó trống trải trên sheet
2. Copy kể từ dòng 10 của vùng này vào 1 array khác
3. Gán array mới vào đúng nơi mong muốn
4. Delete vùng tạm
Cách 2
1. Gán cả mảng vào nơi mong muốn
2. Delete 9 dòng đầu

Anh @VetMini làm em giật mình, em tưởng em sử dụng sai thuật ngữ nhưng em kiểm tra lại thì không sai. Hihi... (em xin gửi hình và link SheetForm của 1 trang web dạy Vba Excel khá nổi tiếng ở dưới ạ)

Giá trị Array(10 to 15, 1 to 6) đại khái là mảng 2 chiều có dữ liệu từ dòng 1 đến dòng 15, cột 1 đến cột 6 nhưng em chỉ cần lấy dữ liệu từ dòng 10 đến dòng 15 và cột 1 đến cột 6 thôi ạ. (Có khả năng trình độ em kém em sử dụng thuật ngữ sai, mong anh bỏ qua giúp em)

Tình hình là 2 cách anh đưa ra thì không cách nào khả thi hết
Cách 1 thì mất nhiều công đoạn quá,
Còn cách 2 thì nếu có dữ liệu trước vị trí cần thêm dữ liệu thì cũng hơi căng à :)

1581180325102.png
 
Upvote 0
Anh @VetMini làm em giật mình, em tưởng em sử dụng sai thuật ngữ nhưng em kiểm tra lại thì không sai. Hihi... (em xin gửi hình và link SheetForm của 1 trang web dạy Vba Excel khá nổi tiếng ở dưới ạ)

Giá trị Array(10 to 15, 1 to 6) đại khái là mảng 2 chiều có dữ liệu từ dòng 1 đến dòng 15, cột 1 đến cột 6 nhưng em chỉ cần lấy dữ liệu từ dòng 10 đến dòng 15 và cột 1 đến cột 6 thôi ạ. (Có khả năng trình độ em kém em sử dụng thuật ngữ sai, mong anh bỏ qua giúp em)

Tình hình là 2 cách anh đưa ra thì không cách nào khả thi hết
Cách 1 thì mất nhiều công đoạn quá,
Còn cách 2 thì nếu có dữ liệu trước vị trí cần thêm dữ liệu thì cũng hơi căng à :)

View attachment 231770
Cả 2 cách của bác Vetmini đều khả thi nhé

Anh giải thích rõ hơn chổ "Biến của Array(10 to 15, 1 to 6)" giúp em ạ?
Em ví dụ có file bên dưới.
Thì tôi nghĩ bạn có khai báo 1 biến Array theo cách: Dim a As Array(10 to 15, 1 to 6)
Thì sẽ làm như bài trên tôi chỉ.

Tuy thế, thấy các bài sau bạn giải thích là muốn gán 1 phần Array thôi, thì cách tốt nhất là: Đổ cái phần giá trị Array đó ra 1 biến Array nhỏ - rồi gán Array nhỏ xuống Sheet thôi.

Việc "Đổ cái phần giá trị", thì chắc không phải bàn, bạn đã biết, dùng cách nào thì tùy - có thể dùng FOR cũng nhanh chán, đảm bảo chưa đến 1/10 nốt nhạc thì đã đổ xong cho bảng 6*6
 
Upvote 0
Giả sử, em có mảng 2 chiều Array(1 to 15, 1 to 6)
Giờ em muốn gán các giá trị Array(10 to 15, 1 to 6) xuống SheetForm không dùng vòng lặp bằng cách nào ạ?
Bạn hãy cho biết cách mà bạn sở hữu mảng 2 chiều đó; & khi ý biết đạu có cách nào khác nữa chăng!
 
Upvote 0
Giả sử, em mảng 2 chiều Array(1 to 15, 1 to 6)
Giờ em muốn gán các giá trị Array(10 to 15, 1 to 6) xuống SheetForm không dùng vòng lặp bằng cách nào ạ?
Ngoài các cách của bác VetMini thì cũng có thể dùng hàm INDEX.

Mã:
Sub TestArray()
Dim A(1 To 15, 1 To 6) As Long
Dim r As Long, c As Long, k As Long
Dim arrRow(10 To 15, 1 To 1), arrCol(1 To 6)
'    mảng các chỉ số dòng
    For k = 10 To 15
        arrRow(k, 1) = k
    Next k
'    mảng các chỉ số  cột
    For k = 1 To 6
        arrCol(k) = k
    Next k
    k = 0
'    nhập giá trị vào mảng A
    For r = 1 To 15
        For c = 1 To 6
            k = k + 1
            A(r, c) = k
        Next c
    Next r
'    nhập mảng A xuống sheet để tiện theo dõi mảng 6 dòng
    Range("A1").Resize(15, 6) = A
'    nhập mảng có từ 6 dòng cuối của A xuống sheet, dùng các hằng số mảng
    Range("H1").Resize(6, 6) = Application.Index(A, [{10;11;12;13;14;15}], Array(1, 2, 3, 4, 5, 6))
'    nhập mảng có từ 6 dòng cuối của  A xuống sheet, dùng mảng các chỉ số dòng và mảng các chỉ số cột
    Range("H10").Resize(6, 6) = Application.Index(A, arrRow, arrCol)
   
'    Tương tự trên sheet: chọn vùng H1:M6 -> nhập công thức
'    =INDEX(A1:F15,{10,11,12,13,14,15},{1\2\3\4\5\6}) -> kết thúc bằng Ctrl + Shift + Enter.

'    Về dấu "\" có thể trên mỗi máy khác nhau. Ở đâu đó hãy nhập công thức
'    =SUM(A1:B2) -> trên thanh công thức bôi đen A1:B2 -> nhấn F9. Nhìn thấy
'    giữa 1 và 2 là dấu gì thì thay nó vào vị trí các dấu "\" trong trong công thức ở trên.
   
'    ---------------
'    Phần thưởng thêm, miễn phí
'    1. Nhập mảng các phần tử từ các dòng 7, 8, 11, 14, và từ các cột 1, 3, 5 - mảng các phần tử ở
'    các điểm giao của các dòng 7, 8, 11, 14 và các cột 1, 3, 5
    Range("A20").Resize(4, 3) = Application.Index(A, [{7;8;11;14}], Array(1, 3, 5))
   
'    2. Lấy vùng từ dòng 7 đến 10, cột từ 3 đến 5
    Range("E20").Resize(4, 3) = Application.Index(A, [{7;8;9;10}], Array(3, 4, 5))
'    Tương tự trên sheet: chọn E20:G23 -> nhập công thức
'    =INDEX(A1:F15, {7,8,9,10}, {3\4\5}) -> kết thúc bằng Ctrl + Shift + Enter.
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
... em tưởng em sử dụng sai thuật ngữ nhưng em kiểm tra lại thì không sai. ...
"giá trị Array(10 to 15, 1 to 6)" chắc chắn là sai thuật ngữ. Tuy nhiên có thể tạm đoán được, cũng như con nít nói bập bẹ người ta cũng có hy vọng đoán được.
SheetForm là một tên riêng. Nếu đề cập đến mọt danh tự riêng và khong phổ biến mà không cho biết ngữ cảnh thì cũng là sai thuật ngữ.
 
Upvote 0
"giá trị Array(10 to 15, 1 to 6)" chắc chắn là sai thuật ngữ. Tuy nhiên có thể tạm đoán được, cũng như con nít nói bập bẹ người ta cũng có hy vọng đoán được.
SheetForm là một tên riêng. Nếu đề cập đến mọt danh tự riêng và khong phổ biến mà không cho biết ngữ cảnh thì cũng là sai thuật ngữ.
Ở cái diễn đàn củ khoai này, thì người hỏi (khách hàng không trả tiền) là thượng đế cứ yêu cầu hỏi sao cũng được, người giúp đi mà hiểu, tìm hiểu. Hỏi lại cũng nhiều khi quyết không nói..., được giúp 1 lại muốn 2 ... muốn 3...4 .....--> thế mà tương lai sánh các cường quốc năm châu sao đây (trong khi các cường quốc người ta đẻ ra bộ Office để cho người dùng tiện lợi rồi, vậy mà còn cần giúp cần ... tự động). Lạ thay
 
Lần chỉnh sửa cuối:
Upvote 0
Ở cái diễn đàn củ khoai này, thì người hỏi (khách hàng) là thượng đế cứ yêu cầu hỏi sao cũng được, người giúp đi mà hiểu, tìm hiểu. Hỏi lại cũng nhiều khi quyết không nói..., được giúp 1 lại muốn 2 ... muốn 3...4 .....--> .... Lạ thay
Thiếu điều nói: "Ngu sao không hiểu người ta hỏi gì?" nữa kia đó!
 
Upvote 0

File đính kèm

  • File Test.xlsb
    13 KB · Đọc: 9
Upvote 0
anh @SA_DQ nói quá, em út nào dám đâu. Hic...



Như file em đính kèm, anh xem lại giúp em ạ.
Như dòng đỏ, bạn quyết không nói bắt người ta xem file kèm
Theo ngu kiến của tôi: muốn thuận lợi cho có kết quả thì bạn phải mô tả ra cả ở bài viết lẫn file kèm. Không nên đẩy cái khó cho chính người giúp hay có ý định xem bài giúp mình.
 
Lần chỉnh sửa cuối:
Upvote 0
Như dòng đỏ, bạn quyết không nói bắt người ta xem file kèm
Theo ngu kiến của tôi: muốn thuận lợi cho có kết quả thì bạn phải mô tả ra cả ở bài viết lẫn file kèm

Dạ, ý em có 1 mảng nguồn từ B2:D16, kết quả em cần gán từ B2:D16 ạ

1581239482267.png
 
Upvote 0
Bạn không thể gán khơi khơi, mà muốn gán vùng [B10 : D16] phải có điều kiện nào đó, ví dụ như chỉ lấy 07 dòng cuối trong mảng(?) đem gán, hay. . . .
 
Upvote 0
Dạ, ý em có 1 mảng nguồn từ B2:D16, kết quả em cần gán từ B2:D16 ạ

View attachment 231785
Nếu chỉ là code sai tè le này
trong file
Mã:
Sub test()
    Dim Arr
    Arr = Sheet1.Range("B2:D16").Value
    Sheet1.Range("G2").Resize(6, 6).Value
End Sub

Thì sao lại không là
Mã:
Sub test()
    Dim Arr
    Arr = Sheet1.Range("B10:D16").Value
    Sheet1.Range("G2").Resize(7, 3).Value=Arr
End Sub

hay
Mã:
Sub test()

    Sheet1.Range("G2").Resize(7, 3).Value=Sheet1.Range("B10:D16").Value
End Sub

Nếu tất cả điều trên không đúng nhu cầu thì: Xem lại cách đặt vấn đề của chính mình - nếu không là bịa vấn đề, cũng là đang quá mông lung, không biết mình đang hỏi gì.
 
Lần chỉnh sửa cuối:
Upvote 0
Nếu chỉ là code sai tè le này


Thì sao lại không là
Mã:
Sub test()
    Dim Arr
    Arr = Sheet1.Range("B10:D16").Value
    Sheet1.Range("G2").Resize(7, 3).Value=Arr
End Sub

hay
Mã:
Sub test()

    Sheet1.Range("G2").Resize(7, 3).Value=Sheet1.Range("B10:D16").Value
End Sub

Nếu tất cả điều trên không đúng nhu cầu thì: Xem lại cách đặt vấn đề của chính mình - nếu không là bịa vấn đề, cũng là đang quá mông lung, không biết mình đang hỏi gì.

2 cách của anh thì những bạn vừa học viết code cũng viết được anh ạ, mà cũng chẳng cần viết code chi cho mệt, sử dụng phím tắt Ctrl C và Ctrl V là xong. Nếu đơn giản vậy thì em cũng không đăng câu hỏi để hỏi làm gì

Thứ 1: Chủ đề của topic này đang đề cập đến Array.
Thứ 2: Em đã nói Array đã nhận giá trị từ B2:D16.
Thứ 3: Em cần trích và gán dữ liệu từ B10:D16 xuống vị trí khác.

Cám ơn anh đã nhiệt tình giúp đỡ ạ!
 
Upvote 0
Web KT

Bài viết mới nhất

Back
Top Bottom