Làm sao để nhập dữ liệu trên UserForm có nhiều TextBox, ComboBox?

Liên hệ QC

Hoàng Trọng Nghĩa

Chuyên gia GPE
Thành viên BQT
Moderator
Tham gia
17/8/08
Bài viết
8,662
Được thích
16,720
Giới tính
Nam
Tôi có một UserForm với nhiều TextBox, ComboBox.

Tôi muốn nhập một lần với các TextBox & ComboBox đó, tuy nhiên, việc phát sinh có thể một lần nhập là 1 hàng, hoặc nhiều hàng tùy theo việc phát sinh tại các ComboBox VITRI.

Vậy làm sao có thể nhập nhanh và chính xác các điều kiện trong một lần bấm nút lệnh?

(Nguyên tắc là có Vị trí 1 mới có vị trí 2, không được trên chưa có mà dưới lại có).

Các yêu cầu trong File, xin vui lòng giúp đỡ!

(Form thật có rất nhiều TextBox, ComboBox, File đính kèm chỉ là rút gọn lại)

Xin được cám ơn!
 

File đính kèm

Không biết bài này có thể nhập theo mảng được không nhỉ? Mình nghĩ thì được, tuy nhiên các tên TextBox cũng khác nhau nên khó tập trung vào vòng lặp.
 
Upvote 0
Upvote 0
Chắc mình già rồi, trí óc phản ứng chậm nên đọc bài việt + xem file = chẳng hiểu cóc khô gì

Gán về dạng mảng nó cũng na ná giống bài này nè!

http://www.giaiphapexcel.com/forum/...-hiển-thị-trong-TextBox&p=378858#post378858

Nhưng đây mới là yêu cầu của phần nhập, cũng phải qua được cái này, cái sau sẽ khó hơn, còn việc nhập từng cái từng cái lên sheet thì có gì khó đâu!
 
Upvote 0
Chắc mình già rồi, trí óc phản ứng chậm nên đọc bài việt + xem file = chẳng hiểu cóc khô gì

Không phải già đâu ah, mà là QUÁ GIÀ lun, Vì giọng văn của tác giả hàn lâm quá nên chắc phải người cao thủ (già chút đủ uyên thâm) mới hiểu -- chứ trẻ là chưa đủ để hiểu đâu.

hehe, vui thế, NHƯNG quả đúng là xem không hiểu gì hết thật, chắc biết ý đồ gì nữa, cũng không nói rõ có gì, cần kết quả gì, từ dòng vòng sang mảng, từ hỏi sang kết luận lun,

@tác giả: bạn phải giải thích rõ chút đi, người không biết (trẻ) cũng hiểu lun thì mới được
 
Upvote 0
Hiểu được tức là già, già lắm hả ta?
Eo ui, lão chết tiệt già vậy sao?

Điều quan trọng là đặt tên các controls sao cho nó dễ đọc dễ viết code. Cái này rất căn bản. Thí dụ các textbox COT6 đến COT10 tại sao không đặt TxtBox6 đến TxtBox10? Các combobox VITRI sao không đặt tên từ CbBox1 đến CbBox5?

PHP:
Private Sub CommandButton1_Click()
Dim ResultArr
Dim n As Long, EndR As Long
For i = 1 To 5
    If Left(Me.Controls("CbBox" & i), 5) <> "VITRI" Then n = n + 1
Next

ReDim ResultArr(1 To n, 1 To 10)
For i = 1 To n
    ResultArr(i, 1) = Me.CbboxMS
    ResultArr(i, 2) = Me.TxtboxTen
    ResultArr(i, 3) = Me.TxtBoxCVu
    ResultArr(i, 4) = Me.Controls("Cbbox" & i)
    ResultArr(i, 5) = Me.Controls("TxtboxNgay" & i)
    If i = 1 Then
        For j = 6 To 10
            ResultArr(i, j) = Me.Controls("TxtBox" & j)
        Next
    End If
Next
EndR = Sheet1.[A1000].End(xlUp).Row
Sheet1.Cells(EndR + 1, 1).Resize(n, 10) = ResultArr
End Sub

Một khuyến cáo nữa (nhưng chưa sửa trong form và trong code):
Không đặt trước Property text cho các controls. Để trống dễ kiểm soát và bẫy lỗi hơn. Rủi Len(CbBoxn) nhỏ hơn 5 thì lại phải bẫy lỗi nữa.

Một khuyến cáo nữa (cũng chưa sửa, mệt quá!):
Tab Stop phải đặt đúng thứ tự nhập liệu, để có thể dùng Enter hoặc Tab nhảy sang control kế tiếp.

Một khuyến cáo nữa: Nếu cứ hỏi kiểu này bị cho vô topic "chán quá" ráng chịu. Ngoài ra, mai mốt lão chết tiệt già chết đi, chẳng còn ai hiểu.

Toàn mấy điều căn bản.
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Hiểu được tức là già, già lắm hả ta?
Eo ui, lão chết tiệt già vậy sao?

Điều quan trọng là đặt tên các controls sao cho nó dễ đọc dễ viết code. Cái này rất căn bản. Thí dụ các textbox COT6 đến COT10 tại sao không đặt TxtBox6 đến TxtBox10? Các combobox VITRI sao không đặt tên từ CbBox1 đến CbBox5?

Chỉ có lão chết tiệt là hiểu vấn đề, nhưng nếu đặt theo tên cột thì cũng mệt nhỉ, giả sử tên cột (cột nhiều sao nhớ các thuộc tính sau này sẽ tính toán, chứ TextBox1, rồi 2, rồi 3, một đống textbox sao biết hoặc nhớ đó là TextBox để gán giá trị cột nào?) đâu phải là cột 1, cột 2... hì hì, nói vậy thôi, nhập liệu là dễ rùi, ai cũng làm được (căn bản mà), Nghĩa mồi chài cái dễ để làm cái khó đây!

Thông thường, nhập được thì sửa được, chẳng lẽ nhập trên Form lại sửa trên sheet sao? Sửa trên Form! Căn cứ Mã số (giả sử Mã số chỉ 1 lần nhập), nếu muốn sửa theo mã số, nếu số cần sửa nhiều vị trí hơn, hoặc ít hơn, thì làm sao chuyển từ sheet lên Form các số đã nhập để sửa? Đó là mấu chốt của vấn đề! Rồi sau đó, nhập lại, nếu nhiều hơn hoặc ít hơn Vị trí thì sao?
Nhập lại chỉnh sửa sẽ như thế nào?

Khó nhai đó!
 
Lần chỉnh sửa cuối:
Upvote 0
Hướng giải quyết:

1) Tìm trong cơ sở dữ liệu vài chục ngàn record để có được nhiều nhất là 5 record chứa mã số cần chỉnh sửa (Nói vậy chứ mình không dại lấy mã số làm chuẩn đâu mà lấy thời gian (hàm Now) để thêm 1 cột nữa là thời gian nhập của 1 lần nhập cho tất cả các record, rồi căn cứ vào nó mà tìm kiếm sẽ không bao giờ bị trùng).

2) Chuyển giá trị của toàn bộ cái đã tìm đó lên Form

3) Nếu thực sự muốn nhập chỉnh sửa thì xóa những record (xoá nội dung rồi dời hàng từ dưới lên trên vì nếu dùng định dạng có điều kiện mà delete hàng sẽ bị mất định dạng).

4) Dĩ nhiên chỉ có nước nhập lại chỉnh sửa từ hàng dưới cùng, việc truy xuất dữ liệu, kể cả dùng Pivot cũng đâu cần trật tự!
 
Upvote 0
Căn cứ Mã số (giả sử Mã số chỉ 1 lần nhập), nếu muốn sửa theo mã số, nếu số cần sửa nhiều vị trí hơn, hoặc ít hơn, thì làm sao chuyển từ sheet lên Form các số đã nhập để sửa? Đó là mấu chốt của vấn đề! Rồi sau đó, nhập lại, nếu nhiều hơn hoặc ít hơn Vị trí thì sao?
Nhập lại chỉnh sửa sẽ như thế nào?

Khó nhai đó!
Khó nhai thì cố nhai, muốn nhờ thì nhờ đàng hoàng 1 chút chứ? Thách đố thì không!

Nghĩa mồi chài cái dễ để làm cái khó đây!
Nói cho oai vậy chứ dễ cũng không biết làm, khó cũng không biết làm, thôi thì nhờ cho tử tế đi.

Nếu nói là dễ khó gì, không làm được mới hỏi, thì có gợi ý đây:

Căn cứ vào mã: Tìm mã trên sheet, tìm luôn số lượng dòng dữ liệu của mã đó
Gán dữ liệu mấy dòng đó vào Array
Xoá béng mấy dòng đó đi, nhưng nhớ cái vị trí.
Gán từng phần tử của Array vào các controls trên form. Rõ ràng là phải đặt tên controls cho dễ gán, tốt nhất là đặt tên có đuôi là số, để dùng vòng lặp giảm số dòng lệnh lập đi lập lại.
Chỉnh sửa gì đó
insert 1 số dòng tại vị trí đã nhớ
Gán Array xuống sheet
 
Upvote 0
nhưng nếu đặt theo tên cột thì cũng mệt nhỉ, giả sử tên cột (cột nhiều sao nhớ các thuộc tính sau này sẽ tính toán, chứ TextBox1, rồi 2, rồi 3, một đống textbox sao biết hoặc nhớ đó là TextBox để gán giá trị cột nào?) đâu phải là cột 1, cột 2..

Đặt tên là do mình đặt, đặt sao cho dễ hình dung. Ngoài ra thêm cái số đuôi đâu có mất mát gì. Thí dụ trong file trên tôi đặt CbBox1 đến CbBox5, sửa lại là CbBoxVitri1 đến CbBoxVitri5.
Còn tôi đặt TxtBox từ 6 đến 10 vì nó nằm từ cột 6 đến cột 10. Không hình dung ra được thì thôi đi, đi chết đi.

Trời ơi! Đẻ con ra không biết đặt tên gì cho dễ gọi dễ nhớ?

3) Nếu thực sự muốn nhập chỉnh sửa thì xóa những record (xoá nội dung rồi dời hàng từ dưới lên trên vì nếu dùng định dạng có điều kiện mà delete hàng sẽ bị mất định dạng).
Nên nhớ rằng khi insert dòng, dòng mới sẽ có định dạng của dòng kề trên.
 
Upvote 0
Thật ra không phải là hỏi đố, mà để tiếp thu các ý kiến của các cao thủ có giải pháp đặc biệt hơn không, chứ giải pháp thì đã có rồi, muốn học hỏi thêm các thuật toán của các cao thủ khi dùng Form nhập vào CSDL mà thôi.

Nên nhớ rằng khi insert dòng, dòng mới sẽ có định dạng của dòng kề trên

Đồng ý là vậy, tuy nhiên với trường hợp thêm, còn trường hợp bớt thì cũng xóa thôi. Và vấn đề Isert hàng này em dư sức biết nó và đã làm tại bài này:

http://www.giaiphapexcel.com/forum/...heo-2-điều-kiện-cho-trước&p=376891#post376891

Còn tôi đặt TxtBox từ 6 đến 10 vì nó nằm từ cột 6 đến cột 10.

File thật có đến 50 cái TextBox và ComboBox đan xen lẫn nhau, tên gọi của nó cũng khác nhau, không có trật tự, cứ 1 TextBox mang theo thuộc tính Change, MouseDown, Enter, Exit, KeyPress,... Nếu để tên theo một kiểu TextBoxXXX ComboBoxYYY thì mò trong Code chắc khùng luôn, vì vậy đặt theo tên của cột, ví dụ TxtBHXH, TxtBHYT, CboMaSo, CboViTri(1 đến n), TxtNgayCong(1 đến n), CboKhoiLuong, TxtCacKhoanPhuTroi, TxtNgoaiGio, TxtNgayLe, ... là trực quan hơn!

Thật ra đây là một chương trình để tính lương cho các công ty có nhiều dự án, mỗi nhân viên có thể trong tháng họ làm nhiều nơi khác nhau, và các công trình không bao giờ biết trước được số lượng nhiều ít nên không thể thêm hay bớt cột, vì thế, để quyết toán số ngày theo các nơi làm việc khác nhau cho nên mới phân bố cấu trúc Form hơi khác lạ như vậy.

Nếu như các cao thủ không có cao kiến gì, lúc đó Nghĩa sẽ đưa ra giải pháp, lúc đó đừng nói Nghĩa là người tiên phong đi trước vấn đề này nha KAKAKA. (Nói câu này mà Nghĩa tự thấy mắc cỡ, nhưng đôi khi cũng muốn khích tướng các Thầy, các Sư phụ một tí).
 
Lần chỉnh sửa cuối:
Upvote 0
Dự án gì ghê vậy? Thế mà đưa dữ liệu mẫu tí tẹo cột, lại còn tiêu đề cột 6 đến cột 10, thánh cũng lầm!

Nhưng mà nói thật, nhập liệu bằng form không phải khó, cũng không phải dễ. Cái chính là cấu trúc dữ liệu trên sheet kia! Cấu trúc dữ liệu sao cho vừa dễ nhập, vừa dễ truy xuất sau này nữa chứ.

Nếu như các cao thủ không có cao kiến gì, lúc đó Nghĩa sẽ đưa ra giải pháp, lúc đó đừng nói Nghĩa là người tiên phong đi trước vấn đề này nha KAKAKA

Mỗi bài toán có 1 cách giải. Mỗi giải pháp dù hay cũng chỉ áp dụng đươc cho 1 bài cụ thể. Đi tiên phong thì quá tốt, nhưng không hẳn là sẽ ai cũng áp dụng được. Nhất là trong việc tính lương. Không đơn vị nào tính lương giống đơn vị nào, do đặc thù của từng công ty.

Chỉ có đi tiên phong về các thuật toán, tạo các hàm Sort2DArr, FilterArray, ... như ndu mới xứng đáng tự hào.
 
Upvote 0
Cho tới bây giờ, chưa thấy Các Cao Thủ có cao kiến gì vậy thôi tôi lấy bài tôi đã làm gửi lên, xem ai có cao kiến gì thì sẽ học hỏi thêm vậy!

Cách nhập tên từng Controls vừa theo quy luật vừa giữ được tên của nó dĩ nhiên là dễ hiểu và dễ làm hơn. Chẳng hạn CboMaSo0101

Với CboMaSo là tên Control, với 01 ta có thể hiểu là số hàng, với 01 là số cột của các controls.

Như vậy, nhập dữ liệu từ mảng rồi gán xuống sheet sẽ không còn là vấn đề gì nữa, cũng như Sư phụ PTM0412, tôi đã làm như sau (thật ra tôi đã từng làm trước đây):

PHP:
Private Sub NhapDuLieu()
    On Error Resume Next
    Dim TG As String
    n = 0
    TG = IIf(Nhap, " " & Now, CboListTime.Text)
    For i = 1 To 12
        If Controls("CboViTri" & Format(i, "00") & "04") <> "" Then n = n + 1
    Next
    ReDim Arr(1 To n, 1 To 17)
    For Each Ctrl In Controls
        For i = 101 To 115
            If Val(Right(Ctrl.Name, 4)) = i Then
                Arr(1, i - 100) = Ctrl.Value
            End If
        Next
    Next
    Arr(1, 16) = TG: Arr(1, 17) = 1
    If n > 1 Then
        For i = 2 To n
            For j = 1 To 3
                Arr(i, j) = Arr(1, j)
            Next
            Arr(i, 4) = Controls("CboViTri" & Format(i, "00") & "04")
            Arr(i, 5) = Controls("TxtNgayCong" & Format(i, "00") & "05")
            Arr(i, 16) = TG
            Arr(i, 17) = i
        Next
    End If
    Sheet1.Range("A65536").End(xlUp).Offset(1).Resize(n, 17) = Arr
End Sub

PHP:
Private Sub CmdNhapLieu_Click()
    Nhap = True
    Call NhapDuLieu
End Sub

Việc chỉnh sửa cũng không khó nhai, nhưng chưa thấy ai nói năng gì cả (ẹc ... ẹc ...), chắc ý tưởng này có mình mình nghĩ ra, lạ lùng quá nên chẳng ai bận tâm đây:

Như tôi đã nói, thêm một cột Thời gian nhập để làm cơ sở khi chỉnh sửa, nên tôi thêm 1 ComboBox (tốt hơn là dùng ListBox hoặc ListView để dễ thấy hàng/ nhóm hàng cần chỉnh sửa)

Lấy duy nhất các mốc thời gian đã nhập, nạp vào CBB:

PHP:
Private Sub CboListTime_DropButtonClick()
    'On Error Resume Next
    Arr = Range(Sheet1.[P3], Sheet1.[P65536].End(xlUp)).Value
    If TypeName(Arr) <> "Variant()" Then
        CboListTime.List() = Sheet1.[P3:Q3].Value
    Else
        With CreateObject("Scripting.Dictionary")
            For i = 1 To UBound(Arr, 1)
                Tmp = Arr(i, 1)
                If Not .Exists(Tmp) And Tmp <> "" Then .Add Tmp, i
            Next
            CboListTime.List() = .Keys
        End With
    End If
End Sub

Sau đó cho dùng sự kiện Change để chuyển dữ liệu từ Sheet lên Form:


PHP:
Private Sub CboListTime_Change()
    'On Error Resume Next
    Call Xoa
    Set MyRng = Range(Sheet1.[A3], Sheet1.[A65536].End(xlUp)).Resize(, 17)
    MyRng.Sort Sheet1.[Q3], 1, , , , , , xlNo
    Arr = MyRng.Value
    ReDim MyArr(1 To UBound(Arr, 1), 1 To 16)
    n = 0
    For i = 1 To UBound(Arr, 1)
        If Arr(i, 16) = CStr(CboListTime.Text) Then
            n = n + 1
            For j = 1 To 16
                MyArr(n, j) = Arr(i, j)
            Next
        End If
    Next
    SoHang = n
    For Each Ctrl In Controls
        For i = 101 To 115
            If Val(Right(Ctrl.Name, 4)) = i Then
                Ctrl.Value = MyArr(1, i - 100)
            End If
        Next
    Next
    If n > 1 Then
        For i = 2 To n
            Controls("CboViTri" & Format(i, "00") & "04") = MyArr(i, 4)
            Controls("TxtNgayCong" & Format(i, "00") & "05") = MyArr(i, 5)
        Next
    End If
End Sub

Cuối cùng chỉ là Nhập lại chỉnh sửa thôi:

PHP:
Private Sub CmdNhapChinhSua_Click()
    Dim MyMsg As Long
    MyMsg = MsgBox("Ban co chac nhap nhung chinh sua nay vao CSDL?", vbQuestion + vbYesNo, "Thông báo")
    If vbYes Then
        Nhap = False
        With Range(Sheet1.[A3], Sheet1.[A65536].End(xlUp)).Resize(, 17)
            For i = 1 To SoHang
                Set MyRng = .Find(CboListTime.Text, LookIn:=xlValues, LookAt:=xlWhole)
                If Not MyRng Is Nothing Then MyRng.ClearContents
            Next
        End With
        Call NhapDuLieu
    End If
    Call Xoa
    CkbChinhSua.Value = False
    CboMaSo0101.SetFocus
End Sub

Xin xem file để góp ý cho tôi, vì một cây làm chẳng nên non!

Xem file tại bài này: http://www.giaiphapexcel.com/forum/...có-nhiều-TextBox-ComboBox&p=385417#post385417
 
Lần chỉnh sửa cuối:
Upvote 0
Việc chỉnh sửa cũng không khó nhai, nhưng chưa thấy ai nói năng gì cả (ẹc ... ẹc ...), chắc ý tưởng này có mình mình nghĩ ra, lạ lùng quá nên chẳng ai bận tâm đây:

Nói thiết, code kiết gì đó + ý tưởng mới thì mình thích lắm... nhưng mà.. cóc hiểu tí gì, lấy đâu mà bận tâm?
Từ bài đầu tiên, mô tả sao cho ai cũng hiểu là bà con "bu" lại liền chứ gì
(cũng còn hên, có 1 người hiểu... Ẹc... Ẹc...)
 
Upvote 0
PHP:
        For i = 101 To 115
            If Val(Right(Ctrl.Name, 4)) = i Then
                Arr(1, i - 100) = Ctrl.Value
            End If
        Next

không xài đến chỉ số 01 thì lấy Right 2 ký tự thôi, khỏi trừ 100.

Việc chỉnh sửa cũng không khó nhai, nhưng chưa thấy ai nói năng gì cả (ẹc ... ẹc ...), chắc ý tưởng này có mình mình nghĩ ra, lạ lùng quá nên chẳng ai bận tâm đây
Với Nghĩa, thì chỉ gợi ý, không làm. Hoặc chọc cho tức, sẽ tự làm.
 
Upvote 0
PHP:
        For i = 101 To 115
            If Val(Right(Ctrl.Name, 4)) = i Then
                Arr(1, i - 100) = Ctrl.Value
            End If
        Next



Với Nghĩa, thì chỉ gợi ý, không làm. Hoặc chọc cho tức, sẽ tự làm.


Không phải vậy, em đã làm rồi, nhưng chưa tự ý đưa lên, dọ dẫm tí để xem chừng ý tứ thế nào, nhưng thấy bài có vẽ khó hiểu và chùng xuống nên gửi lên luôn thôi ạ.

không xài đến chỉ số 01 thì lấy Right 2 ký tự thôi, khỏi trừ 100.

Nó sẽ đụng hàng với Vị trí và Ngày công, nên phải xài số cấp 4, không xài cấp 2 được ạ.
 
Upvote 0
Nó sẽ đụng hàng với Vị trí và Ngày công, nên phải xài số cấp 4, không xài cấp 2 được ạ.
Xài 1 cấp (2 ký tự cuối) chỉ cho đoạn code trích dẫn thôi Nghĩa ơi, tức là chỉ vòng For đó. Vì lấy 4 con (Val xong còn 3), rồi trừ đi 100 còn từ 1 đến 15.
Chả lẽ có 201, 301, ... trừ 100 còn 101, 201, và Arr(1, i - 100) có cột thứ 115 hoặc 215?

Thử thay đoạn code trích dẫn bằng:
PHP:
        For i = 1 To 15
            If Val(Right(Ctrl.Name, 2)) = i Then
                Arr(1, i) = Ctrl.Value
            End If
        Next
xem sao?
 
Upvote 0
Xài 1 cấp (2 ký tự cuối) chỉ cho đoạn code trích dẫn thôi Nghĩa ơi, tức là chỉ vòng For đó. Vì lấy 4 con (Val xong còn 3), rồi trừ đi 100 còn từ 1 đến 15.
Chả lẽ có 201, 301, ... trừ 100 còn 101, 201, và Arr(1, i - 100) có cột thứ 115 hoặc 215?

Thử thay đoạn code trích dẫn bằng:
PHP:
        For i = 1 To 15
            If Val(Right(Ctrl.Name, 2)) = i Then
                Arr(1, i) = Ctrl.Value
            End If
        Next
xem sao?

Em kỹ thôi, nhưng Sư phụ xem lại coi, em đặt theo hàng, theo cột, vì vậy nên tại các CboVitri và TxtNgayCong em đặt giống nhau về số đuôi là 04 và 05, chỉ khác về số hàng chẳng hạng như: CboViTri0104, CboViTri0204

Nếu dùng For Each Ctrl In Controls thì chắc chắn nó sẽ quét qua các Control này, nên em đành phải cho nó lấy 4 ký tự và trừ đi 100 là như vậy.
 
Upvote 0
Do sơ ý không kiểm tra kỹ thủ tục xóa hàng, nếu chạy code dưới đây sẽ bị xóa không đủ hết hàng:

Mã:
Private Sub CmdNhapChinhSua_Click()
    Dim MyMsg As Long
    MyMsg = MsgBox("Ban co chac nhap nhung chinh sua nay vao CSDL?", vbQuestion + vbYesNo, "Thông báo")
    If vbYes Then
        Nhap = False
        With [COLOR=#ff0000][B]Range(Sheet1.[A3], Sheet1.[A65536].End(xlUp)).Resize(, 17)[/B][/COLOR]
            For i = 1 To SoHang
                Set MyRng = .Find(CboListTime.Text, LookIn:=xlValues, LookAt:=xlWhole)
                If Not MyRng Is Nothing Then [COLOR=#ff0000][B]MyRng.ClearContents[/B][/COLOR]
            Next
        End With
        Call NhapDuLieu
    End If
    Call Xoa
    CkbChinhSua.Value = False
    CboMaSo0101.SetFocus
End Sub

giờ sửa lại như sau:

Mã:
Private Sub CmdNhapChinhSua_Click()
    Dim MyMsg As Long
    MyMsg = MsgBox("Ban co chac nhap nhung chinh sua nay vao CSDL?", vbQuestion + vbYesNo, "Thông báo")
    If vbYes Then
        Nhap = False
        With [COLOR=#0000cd][B]Range(Sheet1.[P3], Sheet1.[P65536].End(xlUp))[/B][/COLOR]
            For i = 1 To SoHang
                Set MyRng = .Find(CboListTime.Text, LookIn:=xlValues, LookAt:=xlWhole)
                If Not MyRng Is Nothing Then [COLOR=#0000cd][B]MyRng.Offset(, -15).Resize(, 17).ClearContents[/B][/COLOR]
            Next
        End With
        Call NhapDuLieu
    End If
    CkbChinhSua.Value = False
    CboListTime.Text = ""
    CboMaSo0101.SetFocus
End Sub
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Giả sử như có nhiều TextBox cùng nhập theo hàng của CboViTri, thì thuật toán cũng không khác là bao:

Nhập từ FORM xuống SHEET:

PHP:
Private Sub NhapDuLieu()
    On Error Resume Next
    Dim TG As String, h As Long
    n = 0
    TG = IIf(Nhap, " " & Now, CboListTime.Text)
    For i = 1 To 12
        If Controls("CboViTri" & Format(i, "00") & "04") <> "" Then n = n + 1
    Next
    ReDim Arr(1 To n, 1 To 21)
    Arr(1, 20) = TG: Arr(1, 21) = 1
    For Each Ctrl In FrmCStinhLuong.Controls
        For j = 101 To 119
            If Val(Right(Ctrl.Name, 4)) = j Then
                Arr(1, j - 100) = Ctrl.Value
            End If
        Next
        If n > 1 Then
            For i = 2 To n
                h = i * 100
                For j = 1 + h To 19 + h
                    Select Case j
                    Case 1 + h To 3 + h: Arr(i, j - h) = Arr(1, j - h)
                    Case 4 + h To 5 + h, 16 + h To 19 + h
                        If Val(Right(Ctrl.Name, 4)) = j Then
                            Arr(i, j - h) = Ctrl.Value
                        End If
                    End Select
                Next
                Arr(i, 20) = TG: Arr(i, 21) = i
            Next
        End If
    Next
    Sheet1.Range("A65536").End(xlUp).Offset(1).Resize(n, 21) = Arr
    CboMaSo0101.SetFocus
End Sub

Nhập từ SHEET lên FORM:

PHP:
Private Sub CboListTime_Change()
    'On Error Resume Next
    If CboListTime.Enabled = False Then Exit Sub
    Call Xoa
    Set MyRng = Range(Sheet1.[A3], Sheet1.[A65536].End(xlUp)).Resize(, 21)
    MyRng.Sort Sheet1.Range("T3"), 1, Sheet1.Range("U3"), , 1, , , xlNo
    Arr = MyRng.Value
    ReDim MyArr(1 To UBound(Arr, 1), 1 To 20)
    n = 0
    For i = 1 To UBound(Arr, 1)
        If Arr(i, 20) = CStr(CboListTime.Text) Then
            n = n + 1
            For j = 1 To 20
                MyArr(n, j) = Arr(i, j)
            Next
        End If
    Next
    SoHang = n
    For Each Ctrl In FrmCStinhLuong.Controls
        For j = 101 To 119
            If Val(Right(Ctrl.Name, 4)) = j Then
                Ctrl.Value = MyArr(1, j - 100)
            End If
        Next
        If n > 1 Then
            For i = 2 To n
                h = i * 100
                For j = 1 + h To 19 + h
                    Select Case j
                        Case 1 + h To 3 + h: Arr(i, j - h) = Arr(1, j - h)
                        Case 4 + h To 5 + h, 16 + h To 19 + h
                            If Val(Right(Ctrl.Name, 4)) = j Then Ctrl.Value = MyArr(i, j - h)
                    End Select
                Next
            Next
        End If
    Next
End Sub

Từ đây cho thấy, khi sử dụng mảng cho dù đó là từ Form hay từ Sheet, chúng ta đều có thể sử dụng được và nhập liệu một cách nhanh chóng, khoa học.
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Web KT

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

Back
Top Bottom