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

  • Thread starter Thread starter viehoai
  • Ngày gửi Ngày gửi
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ị
 
Chỉ mỗi MultiSelect = TRUE thì không giải quyết được đâu.

Có một điều ít người biết là nếu đúp chuột trên vd. CommandButton thì sẽ có 5 sự kiện được kích hoạt. Có thể làm thí nghiệm như sau: mở tập tin mới -> thêm UserForm1 -> đặt CommandButton1 trên UserForm -> viết code trong UserForm
Mã:
Option Explicit

Private k As Long

Private Sub CommandButton1_Click()
    k = k + 1
    Debug.Print "Click" & k
End Sub

Private Sub CommandButton1_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
    k = k + 1
    Debug.Print "DblClick" & k
End Sub

Private Sub CommandButton1_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
    k = k + 1
    Debug.Print "Down" & k
End Sub

Private Sub CommandButton1_MouseUp(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
    k = k + 1
    Debug.Print "Up" & k
End Sub
-> hiển thị Form -> đúp chuột vào CommandButton1 -> sẽ có kết quả:
Down1
Up2
Click3
DblClick4
Up5

Như thế khi đúp chuột thì có 5 sự kiện được kích hoạt cho CommandButton1, thứ tự là: MouseDown -> MouseUp -> Click -> DblClick -> MouseUp.

Trong nhiều tình huống MouseUp thứ 2 được kích hoạt khi "dưới trỏ chột" đã là control hoàn toàn khác. Tức ta đúp chuột trên control1 và MouseUp thứ 2 không được kích hoạt cho control1 mà nó được kích hoạt cho control2, khi mà ở thời điểm sau khi thực hiện DblClick thì "dưới trỏ chuột" không phải là control1 mà là control2.

Cụ thể trong trường hợp của bạn như thế nào? Bạn hãy thiết lập MultiSelect = TRUE. Khi bạn đúp chuột trong K2 thì có thể KH0007 (đúp chuột gần mép trên của K2), KH0008 (đúp chuột quãng giữa của K2) hoặc KH0009 (đúp chuột gần mép dưới của K2) được chọn trong ListBox. Tại sao? Khi hiển thị Form thì mục KH0007, KH0008 và KH0009 đều nằm gọn trong dòng 2 của sheet so với màn hình. Trên máy bạn với độ phân giải khác thì rất có thể đó là 3 mục KH... khác nhưng bản chất là như nhau. Tức sau khi Form được hiển thị thì trỏ chuột đang ở vị trí của dòng KH0007, KH008 hoăc KH009 trong ListBox . Vì thế MouseUp thứ 2 được kích hoạt cho ListBox. Lúc đó code trong thư viện VBA sẽ chọn KH007, KH0008 hoặc KH0009 tùy theo vị trị chuột lúc đó ở trên dòng của mục KH0007, KH0008 hay KH0009 (dòng dưới trỏ chuột sẽ được chọn).
----------
Theo tôi bạn không dùng Worksheet_BeforeDoubleClick cho sheet DCCN. Bạn có thể đặt 1 Button1 trên sheet vả hiển thị Form từ Button1.
Cám ơn bác rất nhiều nhé, do em làm thiếu mất đoạn code, giờ thì okay rồi ah.

Hy vọng Bác giúp em bẫy lỗi trong trường hợp này ah:
Chọn kiểm tra Từ ngày ... đến ngày ... mà không có dữ liệu (phát sinh) thì cho hiện ra bảng thông báo "Chua phat sinh"
Nhờ bác hỗ trợ giúp em đoạn code. Em cám ơn bác rất nhiều, để hoàn thiện hơn ah !
Mã:
Private Sub LBDMKH_Change()
    Dim Id, i
    Id = LBDMKH.ListIndex
    With Me.LBDMKH
        On Error Resume Next
        If .Selected(Id) Then
            If Not Dic.exists(.List(Id, 0)) Then
                Dic.ADD .List(Id, 0), .List(Id, 0) & ";" & .List(Id, 1) & ";" & .List(Id, 2) & ";" & .List(Id, 3)
            End If
        Else
            Dic.Remove (.List(Id, 0))
        End If
    End With
End Sub
 

File đính kèm

Upvote 0
Cám ơn bác rất nhiều nhé, do em làm thiếu mất đoạn code, giờ thì okay rồi ah.

Hy vọng Bác giúp em bẫy lỗi trong trường hợp này ah:
Chọn kiểm tra Từ ngày ... đến ngày ... mà không có dữ liệu (phát sinh) thì cho hiện ra bảng thông báo "Chua phat sinh"
Nhờ bác hỗ trợ giúp em đoạn code. Em cám ơn bác rất nhiều, để hoàn thiện hơn ah !
Mã:
Private Sub LBDMKH_Change()
    Dim Id, i
    Id = LBDMKH.ListIndex
    With Me.LBDMKH
        On Error Resume Next
        If .Selected(Id) Then
            If Not Dic.exists(.List(Id, 0)) Then
                Dic.ADD .List(Id, 0), .List(Id, 0) & ";" & .List(Id, 1) & ";" & .List(Id, 2) & ";" & .List(Id, 3)
            End If
        Else
            Dic.Remove (.List(Id, 0))
        End If
    End With
End Sub
Hãy mô tả cách thức hoạt động code trong Form cho người khác hiểu.

Tôi chưa tìm hiểu nhưng tôi có câu hỏi. Có thể chọn nhiều mục trong ListBox hay không? Đã có lúc có người đề nghị MultiSelect = TRUE nhưng không thấy bạn phản đối. Bây giờ tôi lại có cảm giác là bạn cho khả năng chọn nhiều trong ListBox.
 
Upvote 0
Tôi chưa tìm hiểu nhưng tôi có câu hỏi. Có thể chọn nhiều mục trong ListBox hay không? Đã có lúc có người đề nghị MultiSelect = TRUE nhưng không thấy bạn phản đối. Bây giờ tôi lại có cảm giác là bạn cho khả năng chọn nhiều trong ListBox.
File khác và câu hỏi trong file cũng khác rồi anh.
Chọn kiểm tra Từ ngày ... đến ngày ... mà không có dữ liệu (phát sinh) thì cho hiện ra bảng thông báo "Chua phat sinh"
Bạn đưa nhầm file à?
Câu hỏi trong file "Trich loc bao cao" bài 1419 xử lý như sau:
1. Cột K chưa được xoá nên chạy ghi đè lên lần chạy trước, đè không hết thì lòi đầu lòi đuôi ra
2. Không có dữ liệu thì sửa lại:
PHP:
    If k = 0 Then
        MsgBox "No data match"
        Exit Sub
    Else
    With Sheet2
         ....
        Range("E15").Offset(k + 3, 0).Value = "=tvnd(R[-2]C[5])"
        .....
    End With
    End If
 
Upvote 0
Hãy mô tả cách thức hoạt động code trong Form cho người khác hiểu.

Tôi chưa tìm hiểu nhưng tôi có câu hỏi. Có thể chọn nhiều mục trong ListBox hay không? Đã có lúc có người đề nghị MultiSelect = TRUE nhưng không thấy bạn phản đối. Bây giờ tôi lại có cảm giác là bạn cho khả năng chọn nhiều trong ListBox.
Đoạn code này là chính là của Bác ndu96081631 đấy ah, do em bỏ sót đoạn code đó, và chỉnh lại xíu thôi.
Đúng là có thể chọn được nhiều đối tượng (em chưa bẫy được ah). Vì ở đây e chỉ chọn ra 1 khách hàng và lấy mã khách hàng thôi. Em rất cám ơn anh đã giúp đỡ. MultiSelect = TRUE thật sự em chưa biết là phải làm như thế nào, hix
Bài đã được tự động gộp:

File khác và câu hỏi trong file cũng khác rồi anh.

Bạn đưa nhầm file à?
Câu hỏi trong file "Trich loc bao cao" bài 1419 xử lý như sau:
1. Cột K chưa được xoá nên chạy ghi đè lên lần chạy trước, đè không hết thì lòi đầu lòi đuôi ra
2. Không có dữ liệu thì sửa lại:
PHP:
    If k = 0 Then
        MsgBox "No data match"
        Exit Sub
    Else
    With Sheet2
         ....
        Range("E15").Offset(k + 3, 0).Value = "=tvnd(R[-2]C[5])"
        .....
    End With
    End If
Em cám ơn bác rất nhiều ah, em làm được rồi.
Qua đây hy vọng bác giúp đỡ em bẫy chỗ form tìm kiếm này với :
- Khi nhấn đúp vào ô K2 (sheet DCCN tìm kiếm DMKH). Hiện form tự động tích vào dòng tiêu đề + 1 mã khách hàng.
+ Em muốn tắt tích chọn tự động này (lúc hiện lên).
+ Khi tích chọn khách hàng mới, tích trước tự bỏ dấu tích cũ (chỉ được chọn 1).
Em làm gì lỡ, mong các bác bỏ qua dùm, em mới tập tành (sưu tầm code về tự nghiên cứu, còn ngu muội lắm ah)
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Qua đây hy vọng bác giúp đỡ em bẫy chỗ form tìm kiếm này với :
- Khi nhấn đúp vào ô K2 (sheet DCCN tìm kiếm DMKH). Hiện form tự động tích vào dòng tiêu đề + 1 mã khách hàng.
+ Em muốn tắt tích chọn tự động này (lúc hiện lên).
Bạn đọc bài #1418 của tôi bạn không hiểu gì à? Vì trong bài đó tôi giải thích tại sao có "tự động tích vào dòng tiêu đề + 1 mã khách hàng". Và tôi đề nghị cách khắc phục. Tôi chỉ nhầm khi viết MultiSelect = True. Phải là False.

Nhắc lại. Để khắc phục tôi đã đề nghị:
1. Click ListBox để chọn -> trong cửa sổ Properties thiết lập MultiSelect = fmMultiSelectSingle. Xem hình.

1.jpg

2. Trong cửa sổ trong hình ở điểm 1 thiết lập ListStyle = fmListStylePlain

3. Do tôi không hiểu ý tưởng đúp chuột trong ô K2 nên tôi đề nghị dùng Button để hiện thị UserForm: trên ribbon chọn thẻ Developer -> nút Insert -> chọn Button

2.jpg

-> nhấn chuột trên sheet và kéo sang chỗ khác rồi nhả chuột để vẽ 1 hình chữ nhật nhỏ -> trong cửa sổ "Assign Macro" vừa nhẩy ra nhấn nút New -> sửa code vừa có thành
Mã:
Sub Button1_Click()
    frm_DMKH.Show
End Sub

4. Xóa code cũ: trong cửa sổ Project - VBAProject đúp chuột vào Sheet6 (DCCN) -> ở phần bên phải xóa hết từ Private Sub Worksheet_BeforeDoubleClick ... tới End Sub

Tôi hướng dẫn để tương lai bạn biết cách làm. Trong tập tin tôi đã làm cho bạn.
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Bạn đọc bài #1418 của tôi bạn không hiểu gì à? Vì trong bài đó tôi giải thích tại sao có "tự động tích vào dòng tiêu đề + 1 mã khách hàng". Và tôi đề nghị cách khắc phục. Tôi chỉ nhầm khi viết MultiSelect = True. Phải là False.

Nhắc lại. Để khắc phục tôi đã đề nghị:
1. Click ListBox để chọn -> trong cửa sổ Properties thiết lập MultiSelect = fmMultiSelectSingle. Xem hình.

View attachment 245900

2. Trong cửa sổ trong hình ở điểm 1 thiết lập ListStyle = fmListStylePlain

3. Do tôi không hiểu ý tưởng đúp chuột trong ô K2 nên tôi đề nghị dùng Button để hiện thị UserForm: trên ribbon chọn thẻ Developer -> nút Insert -> chọn Button

View attachment 245901

-> nhấn chuột trên sheet và kéo sang chỗ khác rồi nhả chuột để vẽ 1 hình chữ nhật nhỏ -> trong cửa sổ "Assign Macro" vừa nhẩy ra nhấn nút New -> sửa code vừa có thành
Mã:
Sub Button1_Click()
    frm_DMKH.Show
End Sub

4. Xóa code cũ: trong cửa sổ Project - VBAProject đúp chuột vào Sheet6 (DCCN) -> ở phần bên phải xóa hết từ Private Sub Worksheet_BeforeDoubleClick ... tới End Sub

Tôi hướng dẫn để tương lai bạn biết cách làm. Trong tập tin tôi đã làm cho bạn.
Em cám ơn bác rất nhiều nha!
Em nghiên cứu kết hợp chọn thành 1 cái form luôn
- Từ ngày ... đến ngày ...
- Mã khách hàng ... Tạo báo cáo
Có chỗ nào không hiểu mong bác chỉ giúp ah.
 
Upvote 0
Chào mọi người. Ví dụ em có chuỗi giá trị từ 0 đến 9; nếu em gõ giá trị 1 và 9 vào 2 ô A1, B1, thì em muốn các ô còn lại sẽ tự động hiện lần lượt theo thứ tự từ bé đến lớn các giá trị còn lại trong tập số {0,9} nghĩa là sẽ hiển thị: 0 2 3 4 5 6 7 8 ở các ô còn lại. mọi người giúp em với ạ!
 
Upvote 0
Chào mọi người. Ví dụ em có chuỗi giá trị từ 0 đến 9; nếu em gõ giá trị 1 và 9 vào 2 ô A1, B1, thì em muốn các ô còn lại sẽ tự động hiện lần lượt theo thứ tự từ bé đến lớn các giá trị còn lại trong tập số {0,9} nghĩa là sẽ hiển thị: 0 2 3 4 5 6 7 8 ở các ô còn lại. mọi người giúp em với ạ!
Dùng 1 vòng lặp từ 0 đến 9 và 1 cái if nếu đã có trong A1, B1 thì bỏ qua, ngược lại thì bỏ vào "các ô còn lại"
 
Upvote 0
Cho em hỏi đưa 2 hoặc nhiều range vào 1 mảng để dùng vòng lặp cùng lúc thì làm như thế nào ạ?
Ví dụ đưa arr = range("A1:A10").value, rồi đưa tiếp arr = range("B1:B10").value nối tiếp phần trước thì làm như nào ạ?
Em cảm ơn!
 
Upvote 0
Cho em hỏi đưa 2 hoặc nhiều range vào 1 mảng để dùng vòng lặp cùng lúc thì làm như thế nào ạ?
Ví dụ đưa arr = range("A1:A10").value, rồi đưa tiếp arr = range("B1:B10").value nối tiếp phần trước thì làm như nào ạ?
Em cảm ơn!
Mỗi range 1 vòng lặp từ 1 đến dòng cuối mỗi range, mảng kết quả chỉ cần 1 mảng
 
Upvote 0
Chào các thầy cô ạ.
Cho em hỏi chút, Chẳng hạn khi chạy code xong. em có 1 mảng 2 chiều:
Res( 1 to 10, 1 to 5)
Nếu em muốn sort ngay trên mảng theo tiêu chí cột Res(1,1) từ A tới Z thì có cách nào không ạ?
Mong thầy cô giúp đỡ.
Em xin cám ơn nhiều ạ
 
Upvote 0
Chào các thầy cô ạ.
Cho em hỏi chút, Chẳng hạn khi chạy code xong. em có 1 mảng 2 chiều:
Res( 1 to 10, 1 to 5)
Nếu em muốn sort ngay trên mảng theo tiêu chí cột Res(1,1) từ A tới Z thì có cách nào không ạ?
Mong thầy cô giúp đỡ.
Em xin cám ơn nhiều ạ
Tôi thấy việc dùng VBA chép mảng lên sheet, sort rồi đưa lại vào mảng cũng là giải pháp tốt mà.
 
Upvote 0
Tôi thấy việc dùng VBA chép mảng lên sheet, sort rồi đưa lại vào mảng cũng là giải pháp tốt mà.
Em cũng làm như vậy. Nhưng không hiểu sao. Cứ mỗi lần sort. Nó bị treo excell luôn. Cảm giác rất là đơ máy ạ. Nên mới nghĩ sort ngay trên mảng kết quả ạ
 
Upvote 0
Chào các thầy cô ạ.
Cho em hỏi chút, Chẳng hạn khi chạy code xong. em có 1 mảng 2 chiều:
Res( 1 to 10, 1 to 5)
Nếu em muốn sort ngay trên mảng theo tiêu chí cột Res(1,1) từ A tới Z thì có cách nào không ạ?
Mong thầy cô giúp đỡ.
Em xin cám ơn nhiều ạ
Có cách tìm kiếm thuật toán sort mảng, ngay GPE cũng nhiều, các từ khóa tìm sau sẽ có kết quả:
Quick sort, Bubble sort
array list sort
 
Upvote 0
Nếu cho vòng lặp chạy vậy thì nó chậm ko ạ? còn cách nào khác ko chú ?
Mỗi dòng dữ liệu dù ở range nào cũng bắt buộc duyệt qua 1 lần, thì thuật toán bắt buộc phải nhiều vòng lặp như thế. Còn thủ thuật thì dùng mảng nhanh hơn dùng Cell và Range
 
Upvote 0
Mỗi dòng dữ liệu dù ở range nào cũng bắt buộc duyệt qua 1 lần, thì thuật toán bắt buộc phải nhiều vòng lặp như thế. Còn thủ thuật thì dùng mảng nhanh hơn dùng Cell và Range
Con vẫn chưa hiểu chú ơi, con lấy ví dụ ở đây, chú giúp con viết một code đưa dữ liệu ở cột A và cột B vào mảng arr giúp con, mục đích là để chọn chạy vòng lặp trong mảng để lấy ra giá trị ko trùng dán vào cột I.

1618717095111.png

Ở đây con ví dụ phần dữ liệu này ở một sheet chứ thật ra bài toán thực tế nó nằm ở nhiều sheet khác nhau, và nhiều cột hơn thế.
Chú viết giúp con một cái code cho con dễ hình dung nhé! Cám ơn chú!
 
Upvote 0
Web KT

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

Back
Top Bottom