VBA cộng mảng liên tục và gián đoạn

Liên hệ QC

hongphuong1997

Thành viên tiêu biểu
Tham gia
12/11/17
Bài viết
771
Được thích
321
Giới tính
Nữ
Kính nhờ các bác và các anh, chị giúp đỡ viết code bài toán về phép cộng mảng bằng cách đơn giản nhưng đầy đủ và dễ hiểu nhất
Cảm ơn!
 

File đính kèm

Các anh chị ơi giúp em với, Anh @Ba Tê bác @HieuCD ơi giúp cháu bài này với ạ!
 
Kính nhờ các bác và các anh, chị giúp đỡ viết code bài toán về phép cộng mảng bằng cách đơn giản nhưng đầy đủ và dễ hiểu nhất
Cảm ơn!
Không cần 2 code, chỉ cần khai báo lại địa chỉ thích hợp
Mã:
Sub GPE()
  Dim sArr(), Res()
  Dim i As Long, j As Long, sR As Long
'Khai báo vùng du lieu và ket qua
  Const sRngStr = "C2:AA13" 'Dia chi vùng du lieu
  Const rRngStr = "C17" 'Dia chi ket qua
  'Const sRngStr = "C35:X46"
  'Const rRngStr = "C50"
  sArr = Range(sRngStr).Value
  sR = UBound(sArr) - 1
  ReDim Res(1 To sR, 1 To UBound(sArr, 2))
  For i = 1 To sR
    For j = 1 To UBound(sArr, 2)
      If TypeName(sArr(i, j)) = "Double" Then Res(i, j) = sArr(i, j) + sArr(i + 1, j)
    Next j
  Next i
  Range(rRngStr).Resize(sR, UBound(Res, 2)) = Res
End Sub
 
Không cần 2 code, chỉ cần khai báo lại địa chỉ thích hợp
Mã:
Sub GPE()
  Dim sArr(), Res()
  Dim i As Long, j As Long, sR As Long
'Khai báo vùng du lieu và ket qua
  Const sRngStr = "C2:AA13" 'Dia chi vùng du lieu
  Const rRngStr = "C17" 'Dia chi ket qua
  'Const sRngStr = "C35:X46"
  'Const rRngStr = "C50"
  sArr = Range(sRngStr).Value
  sR = UBound(sArr) - 1
  ReDim Res(1 To sR, 1 To UBound(sArr, 2))
  For i = 1 To sR
    For j = 1 To UBound(sArr, 2)
      If TypeName(sArr(i, j)) = "Double" Then Res(i, j) = sArr(i, j) + sArr(i + 1, j)
    Next j
  Next i
  Range(rRngStr).Resize(sR, UBound(Res, 2)) = Res
End Sub
Cháu cảm ơn bác @HieuCD , bác ơi bác làm ơn giải thích cho cháu với.
 
Cháu cảm ơn bác @HieuCD , bác ơi bác làm ơn giải thích cho cháu với.
Đọc ghi chú trong code
Mã:
Sub GPE()
  Dim sArr() 'Mang du lieu
  Dim Res() 'Mang ket qua
  Dim i As Long, j As Long, sR As Long
'Khai báo vùng du lieu và ket qua
  Const sRngStr = "C2:AA13" 'Dia chi vùng du lieu
  Const rRngStr = "C17" 'Dia chi ket qua
  'Const sRngStr = "C35:X46"
  'Const rRngStr = "C50"
  sArr = Range(sRngStr).Value 'Gán du lieu vào mang du lieu
  sR = UBound(sArr) - 1 'so dong mang ket qua, it hon mang du lieu 1 dòng
  ReDim Res(1 To sR, 1 To UBound(sArr, 2)) 'Khai báo mang ket qua voi so dòng: sR và so cot: UBound(sArr, 2)
  For i = 1 To sR 'Chay tu dong dau toi dòng cuoi mang ket qua
    For j = 1 To UBound(sArr, 2) 'Chay tu cot dau toi cot cuoi
      If TypeName(sArr(i, j)) = "Double" Then 'Neu có du lieu
        Res(i, j) = sArr(i, j) + sArr(i + 1, j) 'tính ket qua
      End If
    Next j
  Next i
  Range(rRngStr).Resize(sR, UBound(Res, 2)) = Res 'gán ket qua vào dia chi ket qua
End Sub
 
Đọc ghi chú trong code
Mã:
Sub GPE()
  Dim sArr() 'Mang du lieu
  Dim Res() 'Mang ket qua
  Dim i As Long, j As Long, sR As Long
'Khai báo vùng du lieu và ket qua
  Const sRngStr = "C2:AA13" 'Dia chi vùng du lieu
  Const rRngStr = "C17" 'Dia chi ket qua
  'Const sRngStr = "C35:X46"
  'Const rRngStr = "C50"
  sArr = Range(sRngStr).Value 'Gán du lieu vào mang du lieu
  sR = UBound(sArr) - 1 'so dong mang ket qua, it hon mang du lieu 1 dòng
  ReDim Res(1 To sR, 1 To UBound(sArr, 2)) 'Khai báo mang ket qua voi so dòng: sR và so cot: UBound(sArr, 2)
  For i = 1 To sR 'Chay tu dong dau toi dòng cuoi mang ket qua
    For j = 1 To UBound(sArr, 2) 'Chay tu cot dau toi cot cuoi
      If TypeName(sArr(i, j)) = "Double" Then 'Neu có du lieu
        Res(i, j) = sArr(i, j) + sArr(i + 1, j) 'tính ket qua
      End If
    Next j
  Next i
  Range(rRngStr).Resize(sR, UBound(Res, 2)) = Res 'gán ket qua vào dia chi ket qua
End Sub
Cháu cảm ơn bác. cháu hỏi thêm bác tý nhé! Thế cháu muốn cộng 3 hoặc nhiều số liên tiếp (Không phải là cộng 2 số như ví dụ) thì phải thay đổi như nào hả bác?
 
Cháu cảm ơn bác. cháu hỏi thêm bác tý nhé! Thế cháu muốn cộng 3 hoặc nhiều số liên tiếp (Không phải là cộng 2 số như ví dụ) thì phải thay đổi như nào hả bác?
Thêm biến n để hiểu cách
Mã:
Sub GPE()
  Dim sArr() 'Mang du lieu
  Dim Res() 'Mang ket qua
  Dim i As Long, j As Long, sR As Long
  Const n = 3
'Khai báo vùng du lieu và ket qua
  Const sRngStr = "C2:AA13" 'Dia chi vùng du lieu
  Const rRngStr = "C17" 'Dia chi ket qua
  'Const sRngStr = "C35:X46"
  'Const rRngStr = "C50"
  sArr = Range(sRngStr).Value 'Gán du lieu vào mang du lieu
  sR = UBound(sArr) - (n - 1) 'so dong mang ket qua, it hon mang du lieu n-1 dòng
  ReDim Res(1 To sR, 1 To UBound(sArr, 2)) 'Khai báo mang ket qua voi so dòng: sR và so cot: UBound(sArr, 2)
  For i = 1 To sR 'Chay tu dong dau toi dòng cuoi mang ket qua
    For j = 1 To UBound(sArr, 2) 'Chay tu cot dau toi cot cuoi
      If TypeName(sArr(i, j)) = "Double" Then 'Neu có du lieu
        Res(i, j) = sArr(i, j) + sArr(i + 1, j) + sArr(i + 2, j) 'tính ket qua
      End If
    Next j
  Next i
  Range(rRngStr).Resize(sR, UBound(Res, 2)) = Res 'gán ket qua vào dia chi ket qua
End Sub
Hoặc viết lại tổng quát hơn, chưa bẩy lổi n lớn hơn số dòng dữ liệu
Mã:
Sub GPE1()
  Dim sArr() 'Mang du lieu
  Dim Res() 'Mang ket qua
  Dim i As Long, j As Long, sR As Long, k As Byte
  Const n = 3 'so dòng cong
  Const sRngStr = "C2:AA13" 'Dia chi vùng du lieu
  Const rRngStr = "C17" 'Dia chi ket qua
  'Const sRngStr = "C35:X46"
  'Const rRngStr = "C50"
  
  sArr = Range(sRngStr).Value 'Gán du lieu vào mang du lieu
  sR = UBound(sArr) - (n - 1) 'so dong mang ket qua, it hon mang du lieu n-1 dòng
  ReDim Res(1 To sR, 1 To UBound(sArr, 2)) 'Khai báo mang ket qua voi so dòng: sR và so cot: UBound(sArr, 2)
  For i = 1 To sR 'Chay tu dong dau toi dòng cuoi mang ket qua
    For j = 1 To UBound(sArr, 2) 'Chay tu cot dau toi cot cuoi
      If TypeName(sArr(i, j)) = "Double" Then 'Neu có du lieu
        For k = 0 To n - 1
          Res(i, j) = Res(i, j) + sArr(i + k, j) 'tính ket qua
        Next k
      End If
    Next j
  Next i
  Range(rRngStr).Resize(sR, UBound(Res, 2)) = Res 'gán ket qua vào dia chi ket qua
End Sub
 
Thêm biến n để hiểu cách
Mã:
Sub GPE()
  Dim sArr() 'Mang du lieu
  Dim Res() 'Mang ket qua
  Dim i As Long, j As Long, sR As Long
  Const n = 3
'Khai báo vùng du lieu và ket qua
  Const sRngStr = "C2:AA13" 'Dia chi vùng du lieu
  Const rRngStr = "C17" 'Dia chi ket qua
  'Const sRngStr = "C35:X46"
  'Const rRngStr = "C50"
  sArr = Range(sRngStr).Value 'Gán du lieu vào mang du lieu
  sR = UBound(sArr) - (n - 1) 'so dong mang ket qua, it hon mang du lieu n-1 dòng
  ReDim Res(1 To sR, 1 To UBound(sArr, 2)) 'Khai báo mang ket qua voi so dòng: sR và so cot: UBound(sArr, 2)
  For i = 1 To sR 'Chay tu dong dau toi dòng cuoi mang ket qua
    For j = 1 To UBound(sArr, 2) 'Chay tu cot dau toi cot cuoi
      If TypeName(sArr(i, j)) = "Double" Then 'Neu có du lieu
        Res(i, j) = sArr(i, j) + sArr(i + 1, j) + sArr(i + 2, j) 'tính ket qua
      End If
    Next j
  Next i
  Range(rRngStr).Resize(sR, UBound(Res, 2)) = Res 'gán ket qua vào dia chi ket qua
End Sub
Hoặc viết lại tổng quát hơn, chưa bẩy lổi n lớn hơn số dòng dữ liệu
Mã:
Sub GPE1()
  Dim sArr() 'Mang du lieu
  Dim Res() 'Mang ket qua
  Dim i As Long, j As Long, sR As Long, k As Byte
  Const n = 3 'so dòng cong
  Const sRngStr = "C2:AA13" 'Dia chi vùng du lieu
  Const rRngStr = "C17" 'Dia chi ket qua
  'Const sRngStr = "C35:X46"
  'Const rRngStr = "C50"
 
  sArr = Range(sRngStr).Value 'Gán du lieu vào mang du lieu
  sR = UBound(sArr) - (n - 1) 'so dong mang ket qua, it hon mang du lieu n-1 dòng
  ReDim Res(1 To sR, 1 To UBound(sArr, 2)) 'Khai báo mang ket qua voi so dòng: sR và so cot: UBound(sArr, 2)
  For i = 1 To sR 'Chay tu dong dau toi dòng cuoi mang ket qua
    For j = 1 To UBound(sArr, 2) 'Chay tu cot dau toi cot cuoi
      If TypeName(sArr(i, j)) = "Double" Then 'Neu có du lieu
        For k = 0 To n - 1
          Res(i, j) = Res(i, j) + sArr(i + k, j) 'tính ket qua
        Next k
      End If
    Next j
  Next i
  Range(rRngStr).Resize(sR, UBound(Res, 2)) = Res 'gán ket qua vào dia chi ket qua
End Sub
Cháu cảm ơn bác rất nhiều, Giá như cháu được học trực tiếp kiến thức của bác thì cháu sẽ nhanh giỏi lắm. Cháu cảm ơn bác ạ.
 
Thêm biến n để hiểu cách
Mã:
Sub GPE()
  Dim sArr() 'Mang du lieu
  Dim Res() 'Mang ket qua
  Dim i As Long, j As Long, sR As Long
  Const n = 3
'Khai báo vùng du lieu và ket qua
  Const sRngStr = "C2:AA13" 'Dia chi vùng du lieu
  Const rRngStr = "C17" 'Dia chi ket qua
  'Const sRngStr = "C35:X46"
  'Const rRngStr = "C50"
  sArr = Range(sRngStr).Value 'Gán du lieu vào mang du lieu
  sR = UBound(sArr) - (n - 1) 'so dong mang ket qua, it hon mang du lieu n-1 dòng
  ReDim Res(1 To sR, 1 To UBound(sArr, 2)) 'Khai báo mang ket qua voi so dòng: sR và so cot: UBound(sArr, 2)
  For i = 1 To sR 'Chay tu dong dau toi dòng cuoi mang ket qua
    For j = 1 To UBound(sArr, 2) 'Chay tu cot dau toi cot cuoi
      If TypeName(sArr(i, j)) = "Double" Then 'Neu có du lieu
        Res(i, j) = sArr(i, j) + sArr(i + 1, j) + sArr(i + 2, j) 'tính ket qua
      End If
    Next j
  Next i
  Range(rRngStr).Resize(sR, UBound(Res, 2)) = Res 'gán ket qua vào dia chi ket qua
End Sub
Hoặc viết lại tổng quát hơn, chưa bẩy lổi n lớn hơn số dòng dữ liệu
Mã:
Sub GPE1()
  Dim sArr() 'Mang du lieu
  Dim Res() 'Mang ket qua
  Dim i As Long, j As Long, sR As Long, k As Byte
  Const n = 3 'so dòng cong
  Const sRngStr = "C2:AA13" 'Dia chi vùng du lieu
  Const rRngStr = "C17" 'Dia chi ket qua
  'Const sRngStr = "C35:X46"
  'Const rRngStr = "C50"
 
  sArr = Range(sRngStr).Value 'Gán du lieu vào mang du lieu
  sR = UBound(sArr) - (n - 1) 'so dong mang ket qua, it hon mang du lieu n-1 dòng
  ReDim Res(1 To sR, 1 To UBound(sArr, 2)) 'Khai báo mang ket qua voi so dòng: sR và so cot: UBound(sArr, 2)
  For i = 1 To sR 'Chay tu dong dau toi dòng cuoi mang ket qua
    For j = 1 To UBound(sArr, 2) 'Chay tu cot dau toi cot cuoi
      If TypeName(sArr(i, j)) = "Double" Then 'Neu có du lieu
        For k = 0 To n - 1
          Res(i, j) = Res(i, j) + sArr(i + k, j) 'tính ket qua
        Next k
      End If
    Next j
  Next i
  Range(rRngStr).Resize(sR, UBound(Res, 2)) = Res 'gán ket qua vào dia chi ket qua
End Sub
Cháu chào Bác @HieuCD, Bác ơi bác giúp cho cháu đoạn code và chỉ dẫn cho cháu với bác nhé, Cháu cảm ơn bác!
 

File đính kèm

Thắc mắc: Bài này ứng dụng vào việc gì?
(Làm thì được nhưng tôi ít khi thích làm cộng việc mơ hồ)
 
Thắc mắc: Bài này ứng dụng vào việc gì?
(Làm thì được nhưng tôi ít khi thích làm cộng việc mơ hồ)
Dạ, cháu học cách để tịnh tiến mảng thôi bác à, không ứng dụng vào việc gì bác
ndu96081631
à. Bác viết giúp cho cháu làm sao để dễ hiểu nhất và nguyên lý của nó bác à,
 
Hí hí. Vậy là 2 ngày nay Bác @HieuCD làm công cốc rùi. Bác HieuCD của cháu ui :p:p:p
 
Mình cũng mới học thôi. Mà chủ yếu là đi học lỏm 2 Bác yêu của bạn đó
 
Dạ, cháu học cách để tịnh tiến mảng thôi bác à
PHP:
Sub GPE()
Dim sArr(), I As Long, J As Long, K As Long, N As Long, Rws As Long
sArr = Range("C2").Resize(12, 25).Value
Rws = 17
For N = 1 To 3
    ReDim dArr(1 To 9, 1 To 25)
    K = 0
    For I = N To N + 8
        K = K + 1
        For J = 1 To 25
            dArr(K, J) = sArr(I, J) + sArr(I + 1, J)
        Next J
    Next I
    Range("AC" & Rws).Resize(9, 25) = dArr       '----Gán vào cột nào đó.'
    Rws = Rws + 11
Next N
End Sub
 
Cháu chào Bác @HieuCD, Bác ơi bác giúp cho cháu đoạn code và chỉ dẫn cho cháu với bác nhé, Cháu cảm ơn bác!
Mã:
Sub GPE4() 'tong quat
  Dim sArr() 'Mang du lieu
  Dim Res() 'Mang ket qua
  Dim i As Long, j As Long, sR As Long, mk As Byte, nk As Byte
  Const n = 2 'so dòng cong
  Const m = 3 'so mang ket qua
  Const d = 2 'Só dòng trong giua 2 ket qua
  Const sRngStr = "C2:AA13" 'Dia chi vùng du lieu
  Const rRngStr = "C17" 'Dia chi ket qua
  
  sArr = Range(sRngStr).Value 'Gán du lieu vào mang du lieu
  sR = UBound(sArr) - (n - 1 + m - 1) 'so dong mang ket qua
  For mk = 1 To m 'Chay mang ket qua mk
    ReDim Res(1 To sR, 1 To UBound(sArr, 2)) 'Khai báo mang ket qua voi so dòng: sR và so cot: UBound(sArr, 2)
    For i = 1 To sR 'Chay tu dong dau toi dòng cuoi mang ket qua
      For j = 1 To UBound(sArr, 2) 'Chay tu cot dau toi cot cuoi
        If TypeName(sArr(i, j)) = "Double" Then 'Neu có du lieu
          For nk = 0 To n - 1
            Res(i, j) = Res(i, j) + sArr(i + mk + nk - 1, j) 'tính ket qua
          Next nk
        End If
      Next j
    Next i
  Range(rRngStr).Offset((mk - 1) * (sR + d)).Resize(sR, UBound(Res, 2)) = Res 'gán ket qua vào dia chi ket qua
  Next mk
End Sub
 
PHP:
Sub GPE()
Dim sArr(), I As Long, J As Long, K As Long, N As Long, Rws As Long
sArr = Range("C2").Resize(12, 25).Value
Rws = 17
For N = 1 To 3
    ReDim dArr(1 To 9, 1 To 25)
    K = 0
    For I = N To N + 8
        K = K + 1
        For J = 1 To 25
            dArr(K, J) = sArr(I, J) + sArr(I + 1, J)
        Next J
    Next I
    Range("AC" & Rws).Resize(9, 25) = dArr       '----Gán vào cột nào đó.'
    Rws = Rws + 11
Next N
End Sub
Em cảm ơn anh @Ba Tê đã chỉ bảo cho em, nhưng anh ơi em đang vọc vạch từ đầu mà anh bảo em tự làm thì làm sao em có thể làm được? Anh chỉ hướng đẫn em phong cách một số trường hợp cụ thể sau đó em sẽ phát huy được và có khả năng còn giỏi hơn mấy chị
♫ђöล♥ßล†♥†µ♫ và chị @Hương Liên ..... ấy chứ
 
Mã:
Sub GPE4() 'tong quat
  Dim sArr() 'Mang du lieu
  Dim Res() 'Mang ket qua
  Dim i As Long, j As Long, sR As Long, mk As Byte, nk As Byte
  Const n = 2 'so dòng cong
  Const m = 3 'so mang ket qua
  Const d = 2 'Só dòng trong giua 2 ket qua
  Const sRngStr = "C2:AA13" 'Dia chi vùng du lieu
  Const rRngStr = "C17" 'Dia chi ket qua
 
  sArr = Range(sRngStr).Value 'Gán du lieu vào mang du lieu
  sR = UBound(sArr) - (n - 1 + m - 1) 'so dong mang ket qua
  For mk = 1 To m 'Chay mang ket qua mk
    ReDim Res(1 To sR, 1 To UBound(sArr, 2)) 'Khai báo mang ket qua voi so dòng: sR và so cot: UBound(sArr, 2)
    For i = 1 To sR 'Chay tu dong dau toi dòng cuoi mang ket qua
      For j = 1 To UBound(sArr, 2) 'Chay tu cot dau toi cot cuoi
        If TypeName(sArr(i, j)) = "Double" Then 'Neu có du lieu
          For nk = 0 To n - 1
            Res(i, j) = Res(i, j) + sArr(i + mk + nk - 1, j) 'tính ket qua
          Next nk
        End If
      Next j
    Next i
  Range(rRngStr).Offset((mk - 1) * (sR + d)).Resize(sR, UBound(Res, 2)) = Res 'gán ket qua vào dia chi ket qua
  Next mk
End Sub
Bác ơi đúng quá bác @HieuCD cháu cảm ơn bác! Bác là người thầy vĩ đại của cháu, đêm nay cháu nghiên cứu code này bác à, Cháu cảm ơn bác rất nhiều.
 
Mã:
Sub GPE4() 'tong quat
  Dim sArr() 'Mang du lieu
  Dim Res() 'Mang ket qua
  Dim i As Long, j As Long, sR As Long, mk As Byte, nk As Byte
  Const n = 2 'so dòng cong
  Const m = 3 'so mang ket qua
  Const d = 2 'Só dòng trong giua 2 ket qua
  Const sRngStr = "C2:AA13" 'Dia chi vùng du lieu
  Const rRngStr = "C17" 'Dia chi ket qua
 
  sArr = Range(sRngStr).Value 'Gán du lieu vào mang du lieu
  sR = UBound(sArr) - (n - 1 + m - 1) 'so dong mang ket qua
  For mk = 1 To m 'Chay mang ket qua mk
    ReDim Res(1 To sR, 1 To UBound(sArr, 2)) 'Khai báo mang ket qua voi so dòng: sR và so cot: UBound(sArr, 2)
    For i = 1 To sR 'Chay tu dong dau toi dòng cuoi mang ket qua
      For j = 1 To UBound(sArr, 2) 'Chay tu cot dau toi cot cuoi
        If TypeName(sArr(i, j)) = "Double" Then 'Neu có du lieu
          For nk = 0 To n - 1
            Res(i, j) = Res(i, j) + sArr(i + mk + nk - 1, j) 'tính ket qua
          Next nk
        End If
      Next j
    Next i
  Range(rRngStr).Offset((mk - 1) * (sR + d)).Resize(sR, UBound(Res, 2)) = Res 'gán ket qua vào dia chi ket qua
  Next mk
End Sub
Hu hu... hu.... bác ơi, bác chú thích rõ như thế, nhưng cháu không hiểu thuật toán như nào? Thế mà bác viết được như vậy? Bác có thể chỉ dẫn cho cháu nguyên lý như nào được không hả bác?
 
Web KT

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

Back
Top Bottom