Hàm VBA thao tác với ma trận (1 người xem)

Liên hệ QC

Người dùng đang xem chủ đề này

NguyenNgocSon

KEEP WALKING
Tham gia
4/4/08
Bài viết
280
Được thích
833
Nghề nghiệp
Ths. Cầu hầm
Mình có vấn đề thao tác với mảng như file
không biết có cách nào giải quyết vấn đề này ?
Thân !
 

File đính kèm

Có ngay 1 hàm, nhưng chưa tối ưu

PHP:
Function Matrix(Rng As Range, ColTitle1 As Range, RwTitle1 As Range, ColTitle2 As Range, RwTitle2 As Range) As Variant
Dim TmpArr(), SArr()
SaR = RwTitle1.Count: SaC = ColTitle1.Count
ReDim SArr(1 To SaR, 1 To SaC)
TmpR = RwTitle2.Count: TmpC = ColTitle2.Count
ReDim TmpArr(1 To TmpR, 1 To TmpC)
SArr = Rng.Value
For i = 1 To TmpC
    For j = 1 To TmpR
        For k = 1 To SaC
            For h = 1 To SaR
                If RwTitle1(h, 1) = RwTitle2(j, 1) And ColTitle1(1, k) = ColTitle2(1, i) Then
                    TmpArr(j, i) = SArr(h, k): GoTo next2
                End If
            Next
        Next
next2:
    Next
Next
Matrix = TmpArr
End Function

Được cái có thể dùng với thứ tự các cột, dòng bất kỳ của kết quả.

ColTitle1, RwTitle1, ColTitle2, RwTitle2 là gì chắc không cần giải thích nhỉ?
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Theo tôi nghĩ bài này nên viết một hàm xoá hàng và 1 hàng xoá cột trong mảng 2 chiều, sau đó gộp chung lại thành hàm xoá, như vậy mỗi lần mình gọi hàm xoá tại vị trí hàng và vị trí cột thì nó sẻ thực thi ngay, hôm nào rảnh tôi sẽ viết một hàm để gởi lên GPE
 
Upvote 0
Theo tôi nghĩ bài này nên viết một hàm xoá hàng và 1 hàng xoá cột trong mảng 2 chiều, sau đó gộp chung lại thành hàm xoá, như vậy mỗi lần mình gọi hàm xoá tại vị trí hàng và vị trí cột thì nó sẻ thực thi ngay, hôm nào rảnh tôi sẽ viết một hàm để gởi lên GPE
Còn nếu như thứ tự đảo lộn hoặc bị xen kẽ?
 
Upvote 0
mình có thể xoá 1 hàng và 1 cột bất kỳ trong ma trận 2 chiều, vì dạng này em làm rất nhiều trong C++
 
Upvote 0
Thứ nhất: Xoá hàng xoá cột, không phải hàm, mà là thủ tục.
Thứ 2: Khi thứ tự đảo lộn thì không phải xoá cột xoá dòng, mà là sắp xếp theo thứ tự mới
Thứ 3: Khi bị dòng cột khác xen kẽ, thì phải chèn dòng, chèn cột, chứ không phải xoá.
Thứ 4: Khi vừa có số cột dòng ít hơn, vừa bị đảo lộn thứ tự, vừa bị dòng cột khác xen kẽ, thì thuật toán này phá sản.
 
Upvote 0
Có ngay 1 hàm, nhưng chưa tối ưu

PHP:
Function Matrix(Rng As Range, ColTitle1 As Range, RwTitle1 As Range, ColTitle2 As Range, RwTitle2 As Range) As Variant
Dim TmpArr(), SArr()
SaR = RwTitle1.Count: SaC = ColTitle1.Count
ReDim SArr(1 To SaR, 1 To SaC)
TmpR = RwTitle2.Count: TmpC = ColTitle2.Count
ReDim TmpArr(1 To TmpR, 1 To TmpC)
SArr = Rng.Value
For i = 1 To TmpC
    For j = 1 To TmpR
        For k = 1 To SaC
            For h = 1 To SaR
                If RwTitle1(h, 1) = RwTitle2(j, 1) And ColTitle1(1, k) = ColTitle2(1, i) Then
                    TmpArr(j, i) = SArr(h, k): GoTo next2
                End If
            Next
        Next
next2:
    Next
Next
Matrix = TmpArr
End Function

Được cái có thể dùng với thứ tự các cột, dòng bất kỳ của kết quả.

ColTitle1, RwTitle1, ColTitle2, RwTitle2 là gì chắc không cần giải thích nhỉ?

Em check thử có vẻ đáp ứng yêu cầu. Em sẽ kiểm tra thêm nhờ các bác giúp đỡ.
 
Upvote 0
Mình có vấn đề thao tác với mảng như file
không biết có cách nào giải quyết vấn đề này ?
Thân !
Cái này đâu cần phải dùng vba
hlookup cũng vẫn giải quyết được mà
PHP:
=IFERROR(HLOOKUP(H$11,$B$11:$F$15,MATCH($L12,$F$11:$F$15,0),0),0)
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Hlookup 1 Match, Index 2 Match đều được cả. Nhưng nếu không có IfError của 2007 thì công thức dài ngoằng.
Vả lại, tác giả post bài box lập trình phải có nguyên do.
Lão chết tiệt viết hàm VBA cũng có nguyên do.
Bây giờ đố mấy trò của lão chết tiệt làm cách nào giảm thiểu số vòng lặp của 4 cái For next?
 
Lần chỉnh sửa cuối:
Upvote 0
Cái này đâu cần phải dùng vba
hlookup cũng vẫn giải quyết được mà
PHP:
=IFERROR(HLOOKUP(H$11,$B$11:$F$15,MATCH($L12,$F$11:$F$15,0),0),0)
Cám ơn Bác. Đúng là Em muốn viết hàm để xử lý trong trường hợp này để ứng dụng cho công việc
Thân !
 
Upvote 0
Hlookup 1 Match, Index 2 Match đều được cả. Nhưng nếu không có IfError của 2007 thì công thức dài ngoằng.
Vả lại, tác giả post bài box lập trình phải có nguyên do.
Lão chết tiệt viết hàm VBA cũng có nguyên do.
Bây giờ đố mấy trò của lão chết tiệt làm cách nào giảm thiểu số vòng lặp của 4 cái For next?
Có thể tối ưu hóa hàm trên không bác ?
Như sau :
+ Vì ColTitle1 =TRANSPOSE(RwTitle1)
+ Vì ColTitle2 =TRANSPOSE(RwTitle2)
Nên mình xử lý luôn chỗ này
+ Mình định trước cấp của ma trận đích (ví dụ cấp 5x5) nên ColTitle2 =TRANSPOSE(RwTitle2) có thể lấy ra được luôn ma trận chỉ số từ điều kiện này ạ
Cám ơn Bác !
 
Upvote 0
Phải đợi sau 12 giờ mới viết nha Sơn.
 
Upvote 0
Chỉ có thể giảm số lượng tham số đầu vào thôi. Tuy vậy đã giảm thiểu số vòng lặp.
PHP:
Function Matrix2(Rng As Range, ColTitle1 As Range, ColTitle2 As Range)
Dim TmpArr(), SArr(), RwTitle1, RwTitle2
SArrSize = ColTitle1.Count
ReDim SArr(1 To SArrSize, 1 To SArrSize)
TmpArrSize = ColTitle2.Count
ReDim TmpArr(1 To TmpArrSize, 1 To TmpArrSize)
SArr = Rng.Value
RwTitle1 = Application.Transpose(ColTitle1)
RwTitle2 = Application.Transpose(ColTitle2)
For i = 1 To TmpArrSize
    For j = 1 To TmpArrSize
        For k = 1 To SArrSize
            If ColTitle1(1, k) = ColTitle2(1, i) Then
                For h = 1 To SArrSize
                    If RwTitle1(h, 1) = RwTitle2(j, 1) Then
                        TmpArr(j, i) = SArr(h, k): Exit For
                    End If
                Next
            Exit For
            End If
        Next
    Next
Next
Matrix2 = TmpArr
End Function

Đọc lẹ copy lẹ, kẻo nghẽn mạng, chưa 12 giờ nhưng bùn ngủ rồi.
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Dạ để trong tuần này em rảnh em làm thử xem có được hay không? dù không được thì mình cũng học hỏi được gì từ thất bại này
 
Upvote 0
Tối ưu hóa hàm Matrix2 ?

Chỉ có thể giảm số lượng tham số đầu vào thôi. Tuy vậy đã giảm thiểu số vòng lặp.
Đọc lẹ copy lẹ, kẻo nghẽn mạng, chưa 12 giờ nhưng bùn ngủ rồi.
Quả thực, em cam ơn bác ptm0412 nhiều nhiều ạ.
Hiện tại có 1 vấn đề nữa phát sinh em muốn giải quyết dựa trên Code trên. Bác thử xem qua giúp em xem thế nào nhé ( File đính kèm )
Chúc bác luôn khỏe, công tác tốt
Thân !
 

File đính kèm

Upvote 0
Xin các Mod giải thích dùm hàm xoá dòng xóa cột bị lỗi chỗ nào?
nếu như truyền tham trị trực tiếp như vậy thì chạy OK
Mã:
Call xoadong(A(), n, m, 3)
Call xoacot(A(), n, m, 4)
Call xuat2(A(), n, m)

còn như truyền như vậy thì bào lỗi
Mã:
Call xoadong(A(), n, m, dong)
Call xoacot(A(), n, m, cot)
Call xuat2(A(), n, m)
với dong cot được nhập từ bàn phím
xin chân thành cảm ơn
bài này không có bẫy lỗi gì cả chỉ là bài dạng thô thôi, xin cảm ơn
 

File đính kèm

Chỉnh sửa lần cuối bởi điều hành viên:
Upvote 0
Quả thực, em cam ơn bác ptm0412 nhiều nhiều ạ.
Hiện tại có 1 vấn đề nữa phát sinh em muốn giải quyết dựa trên Code trên. Bác thử xem qua giúp em xem thế nào nhé ( File đính kèm )
Chúc bác luôn khỏe, công tác tốt
Thân !
Sơn muốn gộp thành 1 hàm, hay muốn để riêng hàm trên, muốn cộng thì cộng, muốn trừ thì trừ, muốn nối chuỗi thì nối chuõi?
Hay làmuốn phối hợp: vhuổi thì nối, số thì cộng?
 
Upvote 0
Sơn muốn gộp thành 1 hàm, hay muốn để riêng hàm trên, muốn cộng thì cộng, muốn trừ thì trừ, muốn nối chuỗi thì nối chuõi?
Hay làmuốn phối hợp: vhuổi thì nối, số thì cộng?
Em muốn phối hợp anh ạ; và thao tác trong 1 hàm luôn có được không ạ ? ( Nếu đã viết hàm thì mình có thể viết cho trường hộp gồm n ma trận cộng vào ko)
Em cám ơn
 
Upvote 0
Ủa sao kỳ vậySơn, cộng 2ma trận mà không cộng thứ tự gì hết?
Lẽ ra A(m, n) + B(m, n) = C(m, n)
C(i, j) = A(i, j) + B(i, j) chứ?
 
Upvote 0
Giải thích Code VBA

Ủa sao kỳ vậySơn, cộng 2ma trận mà không cộng thứ tự gì hết?
Lẽ ra A(m, n) + B(m, n) = C(m, n)
C(i, j) = A(i, j) + B(i, j) chứ?
Đúng rồi ạ. Thực ra là hàm em muốn viết ý tưởng như sau:
Giả sử có 2 ma trân A, B muốn đưa vào ma trận C theo các chỉ số tương ứng.Dùng hàm Matrix2:
+ Hàm Matrix2 đưa ma trận A vào ma trận C1 theo đúng chỉ số tương ứng
+ Hàm Matrix2 đưa ma trận B vào ma trận C2 theo đúng chỉ số tương ứng
+ Sau đó mới cộng tương ứng 2 ma trận trung gian này để ra ma trận C ( C=C2+C2) cần tính.
Do đó, e muốn hàm gộp các thao tác này thành một hàm thôi ạ.
Cụ thể như file này ạ.
Cám ơn bác quan tâm!
Thân.
 

File đính kèm

Upvote 0
Té ra là qua 3 cái trung gian, và cộng 2 trong số đó:

A-> C1
A -> B -> C2
cuối cùng C1 + C2

Vậy thì làm vầy, kết quả gặp chuỗi thì nối, gặp số thì cộng:

PHP:
Function SumMatrix(SourceRng As Range, SourceColTitle As Range, ColTitle2 As Range, ColTitle3 As Range)
Dim TmpArrB(), TmpArrC1(), TmpArrC2(), TmpArr(), SArray()
Dim SColT(), ColT2(), ColT3()
SArray = SourceRng.Value
    SColT = SourceColTitle.Value
    ColT2 = ColTitle2.Value
    ColT3 = ColTitle3.Value
    ArrSize = SourceColTitle.Count
    ReDim TmpArr(1 To ArrSize, 1 To ArrSize)
    TmpArrC1 = Matrix(SArray, SColT, ColT3)
    TmpArrB = Matrix(SArray, SColT, ColT2)
    TmpArrC2 = Matrix(TmpArrB, ColT2, ColT3)
    For i = 1 To ArrSize
        For j = 1 To ArrSize
            TmpArr(i, j) = TmpArrC1(i, j) + TmpArrC2(i, j)
        Next
    Next
    SumMatrix = TmpArr
    
End Function

Còn Matrix2 đang có đầu vào là range, sửa lại để có thể nhận đầu vào là Array.

PHP:
Function Matrix(SArr, ColTitle1, ColTitle2)
Dim TmpArr(), RwTitle1, RwTitle2
SArrSize = UBound(SArr, 1)
ReDim TmpArr(1 To SArrSize, 1 To SArrSize)
RwTitle1 = Application.Transpose(ColTitle1)
RwTitle2 = Application.Transpose(ColTitle2)
For i = 1 To SArrSize
    For j = 1 To SArrSize
        For k = 1 To SArrSize
            If ColTitle1(1, k) = ColTitle2(1, i) Then
                For h = 1 To SArrSize
                    If RwTitle1(h, 1) = RwTitle2(j, 1) Then
                        TmpArr(j, i) = SArr(h, k): Exit For
                    End If
                Next
            Exit For
            End If
        Next
    Next
Next
Matrix = TmpArr
End Function
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Té ra là qua 3 cái trung gian, và cộng 2 trong số đó:
A-> C1
A -> B -> C2
cuối cùng C1 + C2
Dạ, em cám ơn bác.
Thực ra vẫn nhầm ý thế này ạ:
A-> C1
B -> C2
cuối cùng mới là: C1 + C2
Như vậy đầu vào của hàm như sau: Function SumMatrix(MatranA,chisoA,MatranB,chisoB,Chisogoc) (Ma trận A và B độc lập chứ không phái A -> B)
mới đúng ạ !
 
Lần chỉnh sửa cuối:
Upvote 0
Mệt quá!
Xem mẫu trong file rõ ràng B = Matrix(A, chỉ số A,chỉ số B). Công thức nằm sờ sờ ra.
từ B mới ra C2
Còn C1 lấy trực tiếp từ A.
 
Lần chỉnh sửa cuối:
Upvote 0
Mệt quá!
Xem mẫu trong file rõ ràng B = Matrix(A, chỉ số A,chỉ số B). Công thức nằm sờ sờ ra.
từ B mới ra C2
Còn C1 lấy trực tiếp từ A.
Dạ, em xin lỗi a. Vì em ngại viêt các số của B nên mới lấy như vậy.
Dạng hàm: Function SumMatrix(MatranA,chisoA,MatranB,chisoB,Chisogoc) (Ma trận A và B độc lập chứ không phái A -> B)
Em cám ơn !
20-11 Chúc thầy luôn khỏe, công tác tốt !
 
Lần chỉnh sửa cuối:
Upvote 0
Lần chỉnh sửa cuối:
Upvote 0
Vậy tôi nếu cũng ngại viết code, sửa code thì sao?
Hiện giờ đang rất ngại phải nhận mấy lời chúc đó đó. Nhận rồi cũng như mắc nợ.
Dạ không sao ạ.Vì lỗi này là do em ạ (Lần sau em sẽ chú ý khi yêu cầu %#^#$ - thực ra nhầm quan điểm chút thôi ạ). Cám ơn thầy đã giúp đỡ. Em cám ơn rất nhiều !
Thân.
 
Upvote 0
Nợ trần ai:

PHP:
Function SumMatrix(SRng1 As Range, SColTitle1 As Range, SRng2 As Range, SColTitle2 As Range, RColTitle As Range)
'SRng = Source Range, SColTitle = Source Column Titlles'
'RColTitle = Result Column Titles'
Dim TmpArrC1(), TmpArrC2(), TmpArr(), SArray1(), SArray2()
Dim SColT1(), SColT2(), RColT()
  SArray1 = SRng1.Value
  SArray2 = SRng2.Value
    SColT1 = SColTitle1.Value
    SColT2 = SColTitle2.Value
    RColT = RColTitle.Value
    ArrSize = SColTitle1.Count
    ReDim TmpArr(1 To ArrSize, 1 To ArrSize)
    TmpArrC1 = Matrix(SArray1, SColT1, RColT)
    TmpArrC2 = Matrix(SArray2, SColT2, RColT)
    For i = 1 To ArrSize
        For j = 1 To ArrSize
            If (IsNumeric(TmpArrC1(i, j)) And IsNumeric(TmpArrC2(i, j))) Then
                TmpArr(i, j) = Val(TmpArrC1(i, j)) + Val(TmpArrC2(i, j))
            Else
                TmpArr(i, j) = TmpArrC1(i, j) & TmpArrC2(i, j)
            End If
        Next
    Next
    SumMatrix = TmpArr
    
End Function
 

File đính kèm

Upvote 0
Em cám ơn thầy nhiều ạ. Em đã check thử nhưng có trường hợp sau thì báo lỗi !
(File đính kèm)
 

File đính kèm

Upvote 0
1. Sao không nói rõ là kết quả có thể khác kích thước với nguồn? Ban đầu làm theo kích thước khác nhau, sửa lại kích thước bằng nhau, bây giờ lại té ra lỗi do kích thước khác nhau!

2. Sao trong file để tồn tại 2 function trùng tên Matrix()? Xoá 1 cái đi hoặc đổi tên đi chứ

3. Sao lại đẻ ra chuyện 2 Title trùng nhau B3 và C3 như trong file? Nói trước, nếu trùng title trong nguồn hoặc title kết quả, hoặc trùng trong cả 2, là công sức trước nay vất đi hết, vì thuật toán phá sản.
 

File đính kèm

Upvote 0
3. Sao lại đẻ ra chuyện 2 Title trùng nhau B3 và C3 như trong file? Nói trước, nếu trùng title trong nguồn hoặc title kết quả, hoặc trùng trong cả 2, là công sức trước nay vất đi hết, vì thuật toán phá sản.
Khi em check mà trùng Title vẫn thấy kết quả đúng ?
Nhưng em muốn hỏi: mình có thể tạo hàm dạng mở được không ạ; nếu như đầu vào có n ma trận thì cú pháp hàm dạng như sau:
Function SumMatrix(MatranA,chisoA,...,Matrann,Chison,Chisochung) được không ạ
Em cám ơn !
 
Upvote 0
Khi em check mà trùng Title vẫn thấy kết quả đúng ?

Trùng làm sao mà đúng hết được? Title nguồn trùng nhưng Kết quả không lấy từ title trùng đó thì dĩ nhiên đúng.

Nói về trùng title, không trùng dữ liệu của title đó:

1. Trùng title nguồn:
Khi dò tìm, thuật toán hiện thời lấy dòng đầu hoặc cột đầu trong số các title trùng, dòng sau cột sau không xét tới. Vậy nếu muốn lấy dữ liệu của title sau, thì thuật toán bó tay.

2. Trùng title đích:
Nếu 2 title giống nhau sẽ cho kết quả giống nhau.
Ngoài ra giả sử title nguồn cũng trùng, và muốn đích 1 lấy nguồn 1, đích 2 lấy nguồn 2, ... thì cũng bó tay nốt

Nhưng em muốn hỏi: mình có thể tạo hàm dạng mở được không ạ; nếu như đầu vào có n ma trận thì cú pháp hàm dạng như sau:
Function SumMatrix(MatranA,chisoA,...,Matrann,Chison,Chisochung) được không ạ

Tôi hông biết, để cao thủ khác làm vậy.
 
Upvote 0
Em cám ơn thầy rất nhiều về vấn đề này
Chúc thầy luôn khoẻ !
 
Upvote 0
Bác ptm0412 có thể cho e hỏi đoạn code nào có thể làm được việc sau:
PHP:
Public Function Matran(E As Double, A As Double, J As Double, l As Double)
Dim MT(1 To 6, 1 To 6)
Dim t1, t2, t3, t4, t5 As Double
t1 = E * A / l: t2 = 12 * E * J / (l ^ 3): t3 = 6 * E * J / (l ^ 2): t4 = 4 * E * J / l: t5 = 2 * E * J / l
MT(1, 1) = t1:  MT(1, 2) = 0:   MT(1, 3) = 0:   MT(1, 4) = -t1: MT(1, 5) = 0:   MT(1, 6) = 0
MT(2, 1) = 0:   MT(2, 2) = t2:  MT(2, 3) = t3:  MT(2, 4) = 0:   MT(2, 5) = -t2: MT(2, 6) = t3
MT(3, 1) = 0:   MT(3, 2) = t3:  MT(3, 3) = t4:  MT(3, 4) = 0:   MT(3, 5) = -t3: MT(3, 6) = t5
MT(4, 1) = -t1: MT(4, 2) = 0:   MT(4, 3) = 0:   MT(4, 4) = t1:  MT(4, 5) = 0:   MT(4, 6) = 0
MT(5, 1) = 0:   MT(5, 2) = -t2: MT(5, 3) = -t3: MT(5, 4) = 0:   MT(5, 5) = t2:  MT(5, 6) = -t3
MT(6, 1) = 0:   MT(6, 2) = t3:  MT(6, 3) = t5:  MT(6, 4) = 0:   MT(6, 5) = -t3: MT(6, 6) = t4
Matran = MT
End Function
Khi thực hiện hàm trên: kết quả là dạng mảng cấp 6x6 ta phải chon trước vùng dữ liệu gồm 6 hàng và 6 cột.
Có cách thao tác nào mà ta chỉ cần đặt trỏ chuột vào 1 ô nào đó, sau đó từ vị trí này code tự lấy vùng dữ liệu gồm 6 hàng, 6 cột không ạ (Lấy về phía dưới, bên phải vj trí trỏ chuột)?
Em cám ơn !
 
Upvote 0
Bác ptm0412 có thể cho e hỏi đoạn code nào có thể làm được việc sau:
PHP:
Public Function Matran(E As Double, A As Double, J As Double, l As Double)
Dim MT(1 To 6, 1 To 6)
Dim t1, t2, t3, t4, t5 As Double
t1 = E * A / l: t2 = 12 * E * J / (l ^ 3): t3 = 6 * E * J / (l ^ 2): t4 = 4 * E * J / l: t5 = 2 * E * J / l
MT(1, 1) = t1:  MT(1, 2) = 0:   MT(1, 3) = 0:   MT(1, 4) = -t1: MT(1, 5) = 0:   MT(1, 6) = 0
MT(2, 1) = 0:   MT(2, 2) = t2:  MT(2, 3) = t3:  MT(2, 4) = 0:   MT(2, 5) = -t2: MT(2, 6) = t3
MT(3, 1) = 0:   MT(3, 2) = t3:  MT(3, 3) = t4:  MT(3, 4) = 0:   MT(3, 5) = -t3: MT(3, 6) = t5
MT(4, 1) = -t1: MT(4, 2) = 0:   MT(4, 3) = 0:   MT(4, 4) = t1:  MT(4, 5) = 0:   MT(4, 6) = 0
MT(5, 1) = 0:   MT(5, 2) = -t2: MT(5, 3) = -t3: MT(5, 4) = 0:   MT(5, 5) = t2:  MT(5, 6) = -t3
MT(6, 1) = 0:   MT(6, 2) = t3:  MT(6, 3) = t5:  MT(6, 4) = 0:   MT(6, 5) = -t3: MT(6, 6) = t4
Matran = MT
End Function
Khi thực hiện hàm trên: kết quả là dạng mảng cấp 6x6 ta phải chon trước vùng dữ liệu gồm 6 hàng và 6 cột.
Có cách thao tác nào mà ta chỉ cần đặt trỏ chuột vào 1 ô nào đó, sau đó từ vị trí này code tự lấy vùng dữ liệu gồm 6 hàng, 6 cột không ạ (Lấy về phía dưới, bên phải vj trí trỏ chuột)?
Em cám ơn !
Thì viết thêm 1 sub nữa
Ví dụ thế này:
PHP:
Sub Test()
  Dim E As Double, A As Double, J As Double, l As Double
  E = bao nhiêu?
  A = bao nhiêu?
  J = bao nhiêu?
  l = bao nhiêu?
  ActiveCell.Resize(6, 6).Value = Matran(E, A, J, l)
End Sub
Đặt con trỏ chuột vào 1 cell rồi chạy sub này ---> không khó đối với bạn chứ?
 
Upvote 0
Upvote 0
Em cám ơn hai bác. Nhưng quả thực nếu không tạo Sub khác thì không giải quyết được vấn đề này sao?
Thân !
 
Upvote 0
Hoặc viết công thức = Index(Matran(E,A,J,l),Rows($1:1),Columns($A:A))
rồi fill qua phải và xuống dưới.
Cái này mà dùng INDEX thì.. hơi phí sư phụ à
Nếu dùng công thức, ta cứ quét chọn 6 dòng, 6 cột rồi gõ vào thanh Formula công thức =Matran(E,A,J,l), bấm Ctrl + Shift + Enter là được rồi
-----------------------------------
Em cám ơn hai bác. Nhưng quả thực nếu không tạo Sub khác thì không giải quyết được vấn đề này sao?
Thân !
Thế bạn có ý tưởng gì khác chăng? Hoặc giả ý bạn mong muốn nó phải như thế nào?
 
Upvote 0
Cái này mà dùng INDEX thì.. hơi phí sư phụ à
Nếu dùng công thức, ta cứ quét chọn 6 dòng, 6 cột rồi gõ vào thanh Formula công thức =Matran(E,A,J,l), bấm Ctrl + Shift + Enter là được rồi
-----------------------------------
Đúng là em đang thao tác hàm trên như đúng ý bác nói.
Nhưng em mong muốn như thế này:
+ Em không muốn quét đồng thời 6 dòng , 6 cột
+ Khi thực hiện hàm chỉ cần chọn 1 ô bất kỳ để gõ hàm, sau đó thì hàm sẽ tự chọn 6 hàng, 6 cột để tính ra kết quả của hàm này.
+ Có thể bẫy lỗi như sau không ạ: Khi mình quét chọn không đủ 6 hàng , 6 cột sẽ đưa ra thông báo lỗi
Em cám ơn!
 
Upvote 0
Đúng là em đang thao tác hàm trên như đúng ý bác nói.
Nhưng em mong muốn như thế này:
+ Em không muốn quét đồng thời 6 dòng , 6 cột
+ Khi thực hiện hàm chỉ cần chọn 1 ô bất kỳ để gõ hàm, sau đó thì hàm sẽ tự chọn 6 hàng, 6 cột để tính ra kết quả của hàm này.
+ Có thể bẫy lỗi như sau không ạ: Khi mình quét chọn không đủ 6 hàng , 6 cột sẽ đưa ra thông báo lỗi
Em cám ơn!
Dùng sự kiện WorksheetChange xem!
Chẳng hạn thế này:
PHP:
Private Sub Worksheet_Change(ByVal Target As Range)
  On Error GoTo ExitSub
  If Left(Target.Formula, 7) = "=Matran" Then Target.Resize(6, 6).FormulaArray = Target.Formula
ExitSub:
End Sub
Bạn nói rằng:
+ Khi thực hiện hàm chỉ cần chọn 1 ô bất kỳ để gõ hàm, sau đó thì hàm sẽ tự chọn 6 hàng, 6 cột để tính ra kết quả của hàm này.
Vậy sao lại thêm:
+ Có thể bẫy lỗi như sau không ạ: Khi mình quét chọn không đủ 6 hàng , 6 cột sẽ đưa ra thông báo lỗi
Chỉ gõ công thức tại 1 cell, có cần quét gì đâu mà bẫy lỗi
 
Upvote 0
Bạn nói rằng:
+ Khi thực hiện hàm chỉ cần chọn 1 ô bất kỳ để gõ hàm, sau đó thì hàm sẽ tự chọn 6 hàng, 6 cột để tính ra kết quả của hàm này.
Chỉ gõ công thức tại 1 cell, có cần quét gì đâu mà bẫy lỗi
Dòng dứơi là e viết:"+ Có thể bẫy lỗi như sau không ạ: Khi mình quét chọn không đủ 6 hàng , 6 cột sẽ đưa ra thông báo lỗi" với mục đích là nếu không xử lý được như yêu cầu trên thì mình dùng cách chọn 6 hàng, 6 cột, nếu không được mới thông báo lỗi.
Thực ra 2 ý khác nhau ạ
Em cám ơn !
 
Upvote 0
Định dạng với mảng

Em có đoạn hai đoạn mã sau:
PHP:
' Ham danh so Thu tu
Public Function Vecto(SoAn As Integer)
Dim A(), n
n = SoAn
ReDim A(1 To n)
For i = 1 To n
A(i) = i
Next i
Vecto = A
Call Macro1
End Function
' Thu tuc dinh dang so
Sub Macro1()
    Selection.NumberFormat = """(""#0"")"""
End Sub
Em muốn hỏi cách đưa định dạng trong Macro1 vào Hàm Vecto để các giá trị trong Vecto có định dạng """(""#0"")"""
Em cám ơn !
 
Upvote 0
Em có đoạn hai đoạn mã sau:
PHP:
' Ham danh so Thu tu
Public Function Vecto(SoAn As Integer)
Dim A(), n
n = SoAn
ReDim A(1 To n)
For i = 1 To n
A(i) = i
Next i
Vecto = A
Call Macro1
End Function
' Thu tuc dinh dang so
Sub Macro1()
    Selection.NumberFormat = """(""#0"")"""
End Sub
Em muốn hỏi cách đưa định dạng trong Macro1 vào Hàm Vecto để các giá trị trong Vecto có định dạng """(""#0"")"""
Em cám ơn !
Bạn có 2 cách để lựa chọn:
- Hoặc là chuyển toàn bộ sang chuổi (dùng hàm Format để định dạng) trực tiếp trong các phần tử của mảng
- Hoặc là làm xong mọi việc, gán giá trị xuống sheet, sau đó sẽ định dạng các cell
 
Upvote 0
Hàm kiểm tra mảng đối xứng

Em mới viết hàm sau để kiểm tra xem mảng nhập vào có đối xứng không. Code như sau:
PHP:
Public Function MTDX(Matrakiemtra As Range)
Dim m, n, i, j As Integer
m = Matrakiemtra.Rows.Count
n = Matrakiemtra.Columns.Count
For i = 1 To m
For j = 1 To n
If Matrakiemtra(i, j) = Matrakiemtra(j, i) Then
MsgBox "Ma tran doi xung qua duong cheo chinh", vbCritical, "Nguyen Ngoc Son"
Else
MsgBox "Ma tran khong doi xung qua duong cheo chinh", vbCritical, "Nguyen Ngoc Son"
End If
Next j
Next i
End Function
Như vậy có cần thiết hàm trả về kết quả không? Mong các bác chỉ giúp ( Vì em dùng thông báo trên hàm khó thoát khỏi thông báo)
Em cám ơn!
Thân !
 
Lần chỉnh sửa cuối:
Upvote 0
PHP:
Public Function MTDX(Matran As Range) As Boolean
Dim m, n, i, j As Integer
MTDX = True
m = Matran.Rows.Count
n = Matran.Columns.Count
For i = 1 To m
    For j = 1 To n
        If Matran(i, j) <> Matran(j, i) Then
            MTDX = False
            Exit Function
        End If
    Next j
Next i
End Function

Cú pháp hàm:
=MTDX(A1:C3)
 
Lần chỉnh sửa cuối:
Upvote 0
Chào các bác,
E là thành viên mới, đang phải tự học VBA vì công việc có liên quan. Hôm nay e có 1 vấn đề liên quan đến ma trận, mảng mà chưa biết cách giải quyết, mong các bác giúp e. Thank in advance.

Đề bài :(hơi dài 1 chút, mong các bác cố gắng đọc, rất thú vị :))
Cho 1 dẫy số : 2,4,3,5,1,4,3,6,5,7,2,6,3,5,2,3,1,8,2,4,1,8,6

Yêu cầu :
Lập trình thuật toán (Tên tiếng anh là Rainflow) cho dẫy số trên. Tính chất thuật toán Rainflown :
- Xét 4 số đầu tiên trong 1 dẫy nếu thỏa mãn điều kiện :số thứ 2 và 3 nằm trong khoảng số thứ 1 và 4. thì lấy số thứ 2 và 3 ra khỏi dẫy(remove) ĐẾM vào 1 ma trận n*n (n là số lớn nhất trong dẫy, ở đây n=8). Sau khi số thứ 2 và thứ 3 bị lấy ra khỏi dẫy thì ta lại xét từ đầu 4 số đầu tiên, nếu thỏa mãn điều kiện (thì làm như trên), nếu không thỏa mãn điều kiện ta xét tiếp 4 số tiếp theo (số đầu tiên tính từ số thứ 2)
- ĐẾM cặp số thỏa mãn vào ma trận như thế nào? Số thứ 2 = vị trí hàng trong ma trận(row), số thứ 3= vị trí cột trong ma trận. Nếu có 1 cặp số thì vị trí đó đếm 1, nếu có 2 cặp số giống nhau thì vị trí đó đếm 2....
- Cuối cùng ta in ra dẫy số rút gọn(là dẫy số còn lại của dẫy trên sau khi các cặp số thỏa mãn bị remove)

Thuật toán trình bầy hơi dài và khó hiểu 1 chút. E xin được tính toán bằng tay với dẫy số trên cho các bác hiểu :
- Dấy số đã cho 2,4,3,5,1,4,3,6,5,7,2,6,3,5,2,3,1,8,2,4,1,8,6
- Xét 4 số đầu tiên :2,4,3,5 Ta thấy 4,3 thuộc khoảng 2,5. Vậy remove 4,3 cho vào ma trận 8*8 trong đó vị trí 4*3(hàng 4 cột 3) trong ma trận sẽ đếm giá trị là 1
- Sau khi 4,3 bị remove. Dẫy số sẽ là 2,5,1,4,3,6,5,7,2,6,3,5,2,3,1,8,2,4,1,8,6
- Xét 4 số đầu tiên 2,5,1,4 ta thấy ko thỏa mãn (5,1 không nằm trong 2,4)
- Lại xét tiếp 4 số tiếp theo(tính từ số thứ 2) là 5,1,4,3 ta thấy cũng không thỏa mãn
- Lại xét tiếp 4 số tiếp theo(tính từ số thứ 2 của dẫy trên) là 1,4,3,6 ta thấy thỏa mãn. Vậy cặp số 4,3 được đếm lần 2 trong ma trận 8*8 ở vị trí 4*3
- Dẫy số mới sẽ là 2,5,1,6,5,7,2,6,3,5,2,3,1,8,2,4,1,8,6
Cứ tiếp tục xét như vậy.....

Thuật toán trên e đã code được rồi, nhưng phần ĐẾM ma trận e chưa biết code. Mong các bác cao thủ giúp e, xin cám ơn nhiều. Dưới đây là đoạn code của e về thuật toán :

Sub Button1_Click()

' Creates Input and Output arrays
Dim InputArray As Variant
Dim OutputCollection As Variant

' Set input array
InputArray = CreateArrayFromRange("A2:A24")

' Calculates
Set OutputCollection = CalcAlgorithm(InputArray)

' Prints the result collection out into the shells
PrintCollection OutputCollection

End Sub

' Copies cells to an array
Function CreateArrayFromRange(yourRange As String) As Variant

Dim arrRng()
Dim Rng As range

x = 0

For Each Rng In range(yourRange)
ReDim Preserve arrRng(x)
arrRng(x) = Rng.Value
x = x + 1
Next Rng

CreateArrayFromRange = arrRng

End Function

' This function peforms the main algorithm.
Function CalcAlgorithm(InputArray As Variant) As Collection

' Result is an array that contains the matrix (2-dimensional array)
Dim Result As New Collection


' Checks whether the array's length satisfies the min. length
If UBound(InputArray) < LengthOfSegment Then
MsgBox "Cannot calculate!"
End If

' Copies the input array to a collection
Dim InputCollection As New Collection
Set InputCollection = CopyArrayToCollection(InputArray)

' BEGIN EXECUTE ALGORITHM

Dim CheckBegin, CheckEnd, CheckCount As Integer
CheckBegin = 1
CheckEnd = CheckBegin + 3
CheckCount = InputCollection.Count

Dim MatrixPointIndex As Integer
MatrixPointIndex = 0

Do While CheckEnd <= CheckCount

Dim LowerBound, UpperBound, CheckTarget1, CheckTarget2 As Double
LowerBound = InputCollection(CheckBegin)
UpperBound = InputCollection(CheckEnd)
CheckTarget1 = InputCollection(CheckBegin + 1)
CheckTarget2 = InputCollection(CheckBegin + 2)

Dim IsTarget1Satisfied, IsTarget2Satisfied As Boolean
IsTarget1Satisfied = Check(LowerBound, UpperBound, CheckTarget1)
IsTarget2Satisfied = Check(LowerBound, UpperBound, CheckTarget2)

Dim NewMatrixPoint As MatrixPoint

' If at least one targeted number is satified then reset the checking process (do at begin)
If IsTarget1Satisfied = True And IsTarget2Satisfied = True Then
' Adds a new matrix point to the result list
Set NewMatrixPoint = New MatrixPoint
NewMatrixPoint.DimensionX = CheckTarget1
NewMatrixPoint.DimensionY = CheckTarget2
MatrixPointIndex = MatrixPointIndex + 1
Result.Add NewMatrixPoint, CStr(MatrixPointIndex)
' Removes 2 targets out of the input collection
InputCollection.Remove (CheckBegin + 1)
InputCollection.Remove (CheckBegin + 1)
' Reset beginning check-position
CheckBegin = 1
Else
CheckBegin = CheckBegin + 1
End If

CheckEnd = CheckBegin + 3
CheckCount = InputCollection.Count

Loop



' END EXECUTE ALGORITHM

' Returns the calculated result
Set CalcAlgorithm = Result

End Function

' This function copies an array to a new collection
Function CopyArrayToCollection(InputArray As Variant) As Collection
Dim Output As New Collection

For i = 0 To UBound(InputArray)
Output.Add (InputArray(i))
Next i

Set CopyArrayToCollection = Output
End Function

' Checks whether the target number is in the given range (lowerbound <= x <= upperbound)
Function Check(ByVal LowerBound As Double, ByVal UpperBound As Double, ByVal Target As Double) As Boolean
If Target >= LowerBound And Target <= UpperBound Then
Check = True
ElseIf Target <= LowerBound And Target >= UpperBound Then
Check = True
Else
Check = False
End If

End Function

' Print a given collection to shells
Sub PrintCollection(ByRef InputCollection As Variant)
For Each Point In InputCollection
Debug.Print "(X = " + CStr(Point.DimensionX) + ", Y = " + CStr(Point.DimensionY) + ")"
MsgBox "(X = " + CStr(Point.DimensionX) + ", Y = " + CStr(Point.DimensionY) + ")"
' TODO the Count of Matrix????
Next Point
End Sub


-
 
Upvote 0
Chào các bác,
Đề bài :(hơi dài 1 chút, mong các bác cố gắng đọc, rất thú vị :))
Cho 1 dẫy số : 2,4,3,5,1,4,3,6,5,7,2,6,3,5,2,3,1,8,2,4,1,8,6

Yêu cầu :
Lập trình thuật toán (Tên tiếng anh là Rainflow) cho dẫy số trên. Tính chất thuật toán Rainflown :
- Xét 4 số đầu tiên trong 1 dẫy nếu thỏa mãn điều kiện :số thứ 2 và 3 nằm trong khoảng số thứ 1 và 4. thì lấy số thứ 2 và 3 ra khỏi dẫy(remove) ĐẾM vào 1 ma trận n*n (n là số lớn nhất trong dẫy, ở đây n=8). Sau khi số thứ 2 và thứ 3 bị lấy ra khỏi dẫy thì ta lại xét từ đầu 4 số đầu tiên, nếu thỏa mãn điều kiện (thì làm như trên), nếu không thỏa mãn điều kiện ta xét tiếp 4 số tiếp theo (số đầu tiên tính từ số thứ 2)
- ĐẾM cặp số thỏa mãn vào ma trận như thế nào? Số thứ 2 = vị trí hàng trong ma trận(row), số thứ 3= vị trí cột trong ma trận. Nếu có 1 cặp số thì vị trí đó đếm 1, nếu có 2 cặp số giống nhau thì vị trí đó đếm 2....
- Cuối cùng ta in ra dẫy số rút gọn(là dẫy số còn lại của dẫy trên sau khi các cặp số thỏa mãn bị remove)
Tôi làm mới hoàn toàn chứ không làm theo code của bạn. Test code bằng file đính kèm.
PHP:
Sub GPE()
ActiveSheet.UsedRange.Offset(, 1).ClearContents
Dim InputArr, Result(), S1 As Long, S2 As Long, S3 As Long, S4 As Long, n As Long
InputArr = Range([A2], [A65536].End(xlUp)).Value
n = Application.WorksheetFunction.Max(Range([A2], [A65536].End(xlUp)))
ReDim Result(1 To n, 1 To n)
S1 = 1: S2 = 2: S3 = 3: S4 = 4
Do
    If (InputArr(S2, 1) >= InputArr(S1, 1)) And (InputArr(S3, 1) >= InputArr(S1, 1)) And (InputArr(S2, 1) <= InputArr(S4, 1)) And (InputArr(S3, 1) <= InputArr(S4, 1)) Then
        Result(InputArr(S2, 1), InputArr(S3, 1)) = Result(InputArr(S2, 1), InputArr(S3, 1)) + 1
        InputArr(S2, 1) = "":   InputArr(S3, 1) = ""
        S2 = S2 + 2: S3 = S3 + 2: S4 = S4 + 2
    Else
        S4 = S4 + 1: S3 = S4 - 1: S2 = S3 - 1: S1 = S2 - 1
    End If
Loop Until S4 > UBound(InputArr, 1)
[D2].Resize(n, n).Value = Result
With Application.WorksheetFunction
    InputArr = .Transpose(Split(.Trim(Join(.Transpose(InputArr)))))
End With
[B2].Resize(UBound(InputArr, 1)).Value = InputArr
End Sub
 

File đính kèm

Upvote 0
Cám ơn bác huuthang_bd!
Phần code của bác có 1 chỗ chưa đúng ở chỗ điều kiện(IF) cho các S1, S2, S3, S4. Em đã sửa và thêm vào điều kiện Elseif nhưng cũng không ra đúng kết quả. Em cũng ko biết tại sao.
Theo tính toán bằng tay của em, với dẫy số trên thì kết quả phải trả về lần lượt :(4,3), (4,3),(6,5),(3,5),(2,6),(2,3),(7,1),(2,4),(1,8). Và dẫy số rút gọn là 2 5 1 8 6
Kết quả này cũng trùng với đoạn code e đã tự viêt.

Mong bác huuthang_bd xem lại giúp e. Cám ơn nhiều.

Sau đây là đoạn code của bác e đã sửa (Chỗ in mầu đỏ):

Sub GPE()
ActiveSheet.UsedRange.Offset(, 1).ClearContents
Dim InputArr, Result(), S1 As Long, S2 As Long, S3 As Long, S4 As Long, n As Long
InputArr = Range([A2], [A65536].End(xlUp)).Value
n = Application.WorksheetFunction.Max(Range([A2], [A65536].End(xlUp)))
ReDim Result(1 To n, 1 To n)
S1 = 1: S2 = 2: S3 = 3: S4 = 4
Do
If (InputArr(S4, 1) >= InputArr(S2, 1) >= InputArr(S1, 1)) And (InputArr(S4, 1) >= InputArr(S3, 1) >= InputArr(S1, 1)) Then
Result(InputArr(S2, 1), InputArr(S3, 1)) = Result(InputArr(S2, 1), InputArr(S3, 1)) + 1
InputArr(S2, 1) = "": InputArr(S3, 1) = ""
S2 = S2 + 2: S3 = S3 + 2: S4 = S4 + 2
ElseIf (InputArr(S4, 1) <= InputArr(S2, 1) <= InputArr(S1, 1)) And (InputArr(S4, 1) <= InputArr(S3, 1) <= InputArr(S1, 1)) Then
Result(InputArr(S2, 1), InputArr(S3, 1)) = Result(InputArr(S2, 1), InputArr(S3, 1)) + 1
InputArr(S2, 1) = "": InputArr(S3, 1) = ""
S2 = S2 + 2: S3 = S3 + 2: S4 = S4 + 2
Else
S1 = S1 + 1: S2 = S2 + 1: S3 = S3 + 1: S4 = S4 + 1
End If
Loop Until S4 > UBound(InputArr, 1)
[D2].Resize(n, n).Value = Result
With Application.WorksheetFunction
InputArr = .Transpose(Split(.Trim(Join(.Transpose(InputArr)))))
End With
[B2].Resize(UBound(InputArr, 1)).Value = InputArr
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Cám ơn bác huuthang_bd!
Phần code của bác có 1 chỗ chưa đúng ở chỗ điều kiện(IF) cho các S1, S2, S3, S4. Em đã sửa và thêm vào điều kiện Elseif nhưng cũng không ra đúng kết quả. Em cũng ko biết tại sao.
Theo tính toán bằng tay của em, với dẫy số trên thì kết quả phải trả về lần lượt :(4,3), (4,3),(6,5),(3,5),(2,6),(2,3),(7,1),(2,4),(1,8). Và dẫy số rút gọn là 2 5 1 8 6
Bạn trình bày lại cách bạn thực hiện thủ công xem từng bước xem như thế nào chứ theo những gì bạn mô tả tôi không làm ra kết quả như bạn được.
Nếu sửa lại code và theo như những gì bạn mô tả thì kết quả sẽ như thế này:
Có: 2, 4, 3, 5, 1, 4, 3, 6, 5, 7, 2, 6, 3, 5, 2, 3, 1, 8, 2, 4, 1, 8, 6
Lấy: 4, 3
Còn: 2, 5, 1, 4, 3, 6, 5, 7, 2, 6, 3, 5, 2, 3, 1, 8, 2, 4, 1, 8, 6
Lấy: 4, 3
Còn: 2, 5, 1, 6, 5, 7, 2, 6, 3, 5, 2, 3, 1, 8, 2, 4, 1, 8, 6
Lấy: 6, 5
Còn: 2, 5, 1, 7, 2, 6, 3, 5, 2, 3, 1, 8, 2, 4, 1, 8, 6
Lấy: 3, 5
Còn: 2, 5, 1, 7, 2, 6, 2, 3, 1, 8, 2, 4, 1, 8, 6
Lấy: 2, 3
Còn: 2, 5, 1, 7, 2, 6, 1, 8, 2, 4, 1, 8, 6
Lấy: 2, 4
Còn: 2, 5, 1, 7, 2, 6, 1, 8, 1, 8, 6
 
Upvote 0
Cám ơn bác huuthang_bd !
E xin tính thủ công thuật toán của e cho bác xem!
Có: 2, 4, 3, 5, 1, 4, 3, 6, 5, 7, 2, 6, 3, 5, 2, 3, 1, 8, 2, 4, 1, 8, 6
Lấy: 4, 3
Còn: 2, 5, 1, 4, 3, 6, 5, 7, 2, 6, 3, 5, 2, 3, 1, 8, 2, 4, 1, 8, 6
Lấy: 4, 3
Còn: 2, 5, 1, 6, 5, 7, 2, 6, 3, 5, 2, 3, 1, 8, 2, 4, 1, 8, 6
Lấy: 6, 5
Còn: 2, 5, 1, 7, 2, 6, 3, 5, 2, 3, 1, 8, 2, 4, 1, 8, 6
Lấy: 3, 5
Còn: 2, 5, 1, 7, 2, 6, 2, 3, 1, 8, 2, 4, 1, 8, 6
Lấy: 2, 6
Còn: 2, 5, 1, 7, 2, 3, 1, 8, 2, 4, 1, 8, 6
Lấy: 2, 3
Còn: 2, 5, 1, 7, 1, 8, 2, 4, 1, 8, 6
Lấy: 7, 1
Còn: 2, 5, 1, 8, 2, 4, 1, 8, 6
Lấy: 2, 4
Còn: 2, 5, 1, 8, 1, 8, 6
Lấy: 8,1
Còn: 2, 5, 1, 8, 6

Mong bác xem lại phần code. E mới tìm hiểu về VBA nên cũng ko biết phải sửa đoạn code của bác như nào hic hic
 
Upvote 0
Vậy bạn lấy code này dùng:
PHP:
Sub GPE()
ActiveSheet.UsedRange.Offset(, 1).ClearContents
Dim InArr, MyArr(), Result(), s As Long, n As Long, i As Long
InArr = Range([A2], [A65536].End(xlUp)).Value
n = Application.WorksheetFunction.Max(Range([A2], [A65536].End(xlUp)))
ReDim Result(1 To n, 1 To n)
s = 1
Do
    If (InArr(s + 1, 1) >= InArr(s, 1)) And (InArr(s + 2, 1) >= InArr(s, 1)) And (InArr(s + 1, 1) <= InArr(s + 3, 1)) And (InArr(s + 2, 1) <= InArr(s + 3, 1)) Or (InArr(s + 1, 1) < InArr(s, 1)) And (InArr(s + 2, 1) < InArr(s, 1)) And (InArr(s + 1, 1) > InArr(s + 3, 1)) And (InArr(s + 2, 1) > InArr(s + 3, 1)) Then
        Result(InArr(s + 1, 1), InArr(s + 2, 1)) = Result(InArr(s + 1, 1), InArr(s + 2, 1)) + 1
        ReDim MyArr(1 To UBound(InArr, 1) - 2, 1 To 1)
        For i = 1 To s
            MyArr(i, 1) = InArr(i, 1)
        Next
        For i = s + 3 To UBound(InArr, 1)
            MyArr(i - 2, 1) = InArr(i, 1)
        Next
        InArr = MyArr
        Erase MyArr
        s = 1
    Else
        s = s + 1
    End If
Loop Until s + 3 > UBound(InArr, 1)
[D2].Resize(n, n).Value = Result
[B2].Resize(UBound(InArr, 1)).Value = InArr
End Sub
 
Upvote 0
Góp thêm một code nữa
Mã:
Public Sub Ma()
    Dim Vung, I, J, K, Tam(1 To 4), Wf, Mg(), M
    Set Wf = Application.WorksheetFunction
    Vung = Range([a2], [a100].End(xlUp)).Value
    ReDim Mg(1 To Wf.Max(Vung), 1 To Wf.Max(Vung))
        For I = 1 To UBound(Vung) - 4
            If I = K - 3 Then Exit Sub
                For J = 1 To 4
                    Tam(J) = Vung(I + J - 1, 1)
                Next J
                    If Tam(1) = Wf.Min(Tam) And Tam(4) = Wf.Max(Tam) Or Tam(1) = Wf.Max(Tam) And Tam(4) = Wf.Min(Tam) Then
                        Mg(Tam(2), Tam(3)) = Mg(Tam(2), Tam(3)) + 1
                        Vung(I + 1, 1) = "": Vung(I + 2, 1) = "": K = 0: [b2:b23].ClearContents
                            For J = 1 To UBound(Vung) - M
                                If Vung(J, 1) <> "" Then
                                    K = K + 1
                                    Vung(K, 1) = Vung(J, 1)
                                End If
                            Next J
                                I = 1: M = M + 2
                                [b2].Resize(K) = Vung
                                [c3].Resize(Wf.Max(Vung), Wf.Max(Vung)) = Mg
                    End If
        Next I
End Sub
Đang định Do...Loop thì Hữu Thắng đã "Đu" rồi. Quê quê, hổng thèm "Đu" nữa. Híc, tuổi trẻ nhanh thật
 

File đính kèm

Upvote 0
Em muốn đặt tên vùng bằng VBA cho vùng: An-60:Bn ( Với n=61) thì khai báo bằng VBA như thế nào ?
 
Upvote 0
Em muốn đặt tên vùng bằng VBA cho vùng: An-60:Bn ( Với n=61) thì khai báo bằng VBA như thế nào ?
Đây là một trong các cách:
Mã:
Sub Test()
Dim Vung As Range, n As Long
n = 61
Set Vung = Range("A" & n - 60 & ":B" & n)
MsgBox Vung.Address
End Sub
 
Upvote 0
Khi thao tác với Textbox để nhớ lại kết quả của lần nhập trước vào textbox mình làm như nào ?
 
Upvote 0
Các câu hỏi càng ngày càng đi xa chủ đề "Hàm VBA thao tác với ma trận"
Sơn nên mở chủ đề mới hoặc tìm chủ đề khác thích hợp để hỏi.
 
Upvote 0
Theo cách xử lý ma trận của bạn chắc bạn đang nghiên cứu về tính toán kết cầu theo phương pháp Phần tử hữu hạn phải không?
 
Upvote 0

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

Back
Top Bottom