Hỏi đáp về VBA (các vấn đề căn bản nhất) (1 người xem)

Liên hệ QC

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

havietchuong

Thành viên tiêu biểu
Tham gia
16/6/09
Bài viết
490
Được thích
570
Giới tính
Nam
Nghề nghiệp
Giáo viên tiểu học.
Tôi không biết đặt đặt câu hỏi này nơi nào cho đúng, xin gởi vào đây. Nếu có sai xin thông cảm cho người mới học VBA.
Trong 1 cửa sổ Module có thể ghi nhiều nhiều Macro và mỗi macro có thể ứng với 1 tổ hợp phím nào đó được không?
Tôi thử nhiều lần thì khi được khi không. Không biết nó thế nào? Trong tập tin sau có lỗi gì không trong cách ghi Macro? Cám ơn.
 

File đính kèm

Lần chỉnh sửa cuối:
Hỏi .value = .value ????

Có một đoạn code
PHP:
ActiveSheet.Select
   With Range("a2:r" & [a65000].End(xlUp).Row) 
.Value = .Value
   End With

Vậy quá trình .value = .value nó có giống hàm Text() trong excel không?
Quá trình này nó làm biến đổi những gì?

Cám ơn Anh/CHị
 
Upvote 0
Mình bày cho bạn cách tự học nè!

Nhập từ [A2] đến [A10] các trị tăng dần;
Bắt đầu từ [B2] (đến [B9]) ta lập công thức =[A2]*[A3] & copy xuống cuối;

Sau đó chạy macro sau
PHP:
Sub gpeTuHoc()
 With [A2:B14]
   .Value = .Value
 End With
End Sub

(húc thành công & chớ ỉ lại quá vô GPE.COM nghe bạn!
 
Upvote 0
Có một đoạn code
PHP:
ActiveSheet.Select
   With Range("a2:r" & [a65000].End(xlUp).Row) 
.Value = .Value
   End With

Vậy quá trình .value = .value nó có giống hàm Text() trong excel không?
Quá trình này nó làm biến đổi những gì?

Cám ơn Anh/CHị

Được hiểu như thế này: Với Range("a2:r" & [a65000].End(xlUp).Row) có thể có chứa công thức hay không, thì sau khi chạy thủ tục trên, tất cả range trong địa chỉ trên chỉ còn là giá trị, không chứa công thức nữa (nó tương đương với Copy/ Paste Special Value).

Bạn có thể tự làm và kiểm chứng.
 
Upvote 0
Có một đoạn code
PHP:
ActiveSheet.Select
   With Range("a2:r" & [a65000].End(xlUp).Row) 
.Value = .Value
   End With

Vậy quá trình .value = .value nó có giống hàm Text() trong excel không?
Quá trình này nó làm biến đổi những gì?

Cám ơn Anh/CHị
Nó giống như PasteSpecial\Values ấy ---> Tóm lại, nếu cell có công thức thì code trên sẽ lấy giá tri, bỏ luôn công thức
Vậy code trên sẽ tương đương:
PHP:
ActiveSheet.Select
With Range("a2:r" & [a65000].End(xlUp).Row) 
  .Copy
  .PasteSpecial xlPasteValues
 End With
 
Lần chỉnh sửa cuối:
Upvote 0
mong anh chỉ dẫn giúp, xin dc biết ơn . làm thế nào tôi có thể vô hiệu hóa 1 macro hoặc 1 form vào một ngày định sẵn
 
Upvote 0
mong anh chỉ dẫn giúp, xin dc biết ơn . làm thế nào tôi có thể vô hiệu hóa 1 macro hoặc 1 form vào một ngày định sẵn

Giả sử đến ngày 24/12/2011 trở về sau không cho chạy thủ tục nữa, Bạn làm như sau:

Mã:
Sub RunUntilDate()
    If Date >= [COLOR=#ff0000]#12/24/2011#[/COLOR] Then Exit Sub
    [COLOR=#006400]'Your code here[/COLOR]
End Sub
 
Upvote 0
Nó giống như PasteSpecial\Values ấy ---> Tóm lại, nếu cell có công thức thì code trên sẽ lấy giá tri, bỏ luôn công thức
Vậy code trên sẽ tương đương:
PHP:
ActiveSheet.Select
With Range("a2:r" & [a65000].End(xlUp).Row) 
  .Copy
  .PasteSpecial xlPasteValues
 End With

Ngoài ý nghĩa trên thì .value = .value còn ý nghĩa nào khác không.Em có một form e-xport từ trong phần mềm ra. Tất cả dữ liệu đều không có công thức nhưng đều set ở dạng GÊN Eral từchuộtko hiểu sao em gõ x toàn bị lỗi dấu và con chuot chạy mất khi dùng UNICODE)

Phải có câu này thì file chế biến số liệu mới đúng
 
Upvote 0
Ngoài ý nghĩa trên thì .value = .value còn ý nghĩa nào khác không.Em có một form e-xport từ trong phần mềm ra. Tất cả dữ liệu đều không có công thức nhưng đều set ở dạng GÊN Eral từchuộtko hiểu sao em gõ x toàn bị lỗi dấu và con chuot chạy mất khi dùng UNICODE)

Phải có câu này thì file chế biến số liệu mới đúng
Tôi chưa hiểu công việc của bạn lắm nên không thể trợ giúp
Tuy nhiên, tôi xin giải thích thêm phần .Value = .Value
Như đã nói ở trên, nó gần giống với PasteSpecial\Values nhưng thực chất sẽ có khác... Điểm khác biệt căn bản là cái thằng .Value = .Value nó xử lý theo kiểu mảng nên tốc độ nhanh hơn
Nếu viết cho rõ ra thì code trên phải thế này
PHP:
Sub Test()
  Dim Arr
  Arr = Range("a2:r" & [a65000].End(xlUp).Row).Value
  Range("a2:r" & [a65000].End(xlUp).Row) = Arr
End Sub
Arr = Range("a2:r" & [a65000].End(xlUp).Row).Value ---> Gán giá trị (chỉ lấy giá trị) vào mảng Arr
Range("a2:r" & [a65000].End(xlUp).Row) = Arr ---> Gán nguyên mảng Arr vào vùng dữ liệu (như vậy, cell chỉ còn giá trị, mất công thức)
 
Upvote 0
Sheet & worksheet khác gì nhau?

Em hỏi có câu
For each sheet in sheets và
For each sheet in worksheet

có gì khác nhau không?

worksheet em hình dung giống như 1 file excel phải không?
 
Upvote 0
Hỏi về code

Mình đang học VBA nên cố chuyển những bài tập excel về đạng dùng VBA, mình chưa biết dùng hàm intmode trong VBA như thế nào. Mong các bạn giải quyết giúp mình.Thanks
 

File đính kèm

Upvote 0
Mình đang học VBA nên cố chuyển những bài tập excel về đạng dùng VBA, mình chưa biết dùng hàm intmode trong VBA như thế nào. Mong các bạn giải quyết giúp mình.Thanks
- Tương ứng với hàm INT(a/b) trong Excel thì trong VBA cũng là hàm INT(a/b) hoặc biểu thức a \ b
- Tương ứng với hàm MOD(a,b) trong Excel (không phải là hàm MODE chứ, vì còn có một hàm MODE trong nhóm hàm thống kê nữa) thì trong VBA là biểu thức a mod b
Còn nếu bạn muốn dùng FormulaR1C1 thì bạn cứ Record macro là biết nó ra cái gì ngay thôi mà.
 
Upvote 0
Em hỏi có câu
For each sheet in sheets và
For each sheet in worksheet

có gì khác nhau không?

worksheet em hình dung giống như 1 file excel phải không?

Không hẳn như vậy đâu bạn ạ. 1 Workbook mới là 1 File. Trong 1 File gồm có Worksheet, Chart, Macro, Dialog.
 
Upvote 0
Thanks bạn, mình có gửi kèm file, bạn xem cách dùng của mình không biết sao báo lỗi.
 
Upvote 0
Ban tham khảo file xem sheets nó gồm những gì và Worksheets nó gồm những gì nha.
Từ đó bạn thấy thằng nào là tổ hợp con của thằng nào
Nói tóm lại cái tên của nó đã nói nên điều đó:
-Sheets là toàn bộ các trang có trong Workbook. Nháy chuột phải vào Sheet tabs---Insert : Trong đó có bao nhiêu loại Sheet mà bạn có thể thêm vào Workbook.
-Worksheet là 1 loại Sheet mà User có thể tạo bảng tính và làm việc trực tiếp trên đó. (Nôm na là các sheet bình thường)
-Workbook mới là 1 file. Còn Worksheets là tổ hợp các sheet làm việc trực tiếp trong file.
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Thanks bạn, mình có gửi kèm file, bạn xem cách dùng của mình không biết sao báo lỗi.
Code của bạn bị lỗi tại câu: Set z = (x - y) / 7. Muốn sử dụng câu lệnh Set z = Cái gì đó thì Cái gì đó phải là một đối tượng (Sheet, Range, Control, UserForm,...), còn biểu thức (x - z) / 7 thì bản thân nó đã phát sinh lỗi rồi, bởi vì không thể lấy 2 Range trừ cho nhau theo cách này được.
Sử dụng Record Macro và sửa lại một xíu thì ta được code sau:
PHP:
Sub GPE9()
    With Sheet37
        .Range("F5:F18").FormulaR1C1 = "=INT((RC[-1]-RC[-2])/7)"
        .Range("G5:G18").FormulaR1C1 = "=VLOOKUP(RC[-4],R21C1:R31C3,2,0)"
        .Range("H5:H18").FormulaR1C1 = "=MOD(RC[-3]-RC[-4],7)"
        .Range("I5:I18").FormulaR1C1 = "=VLOOKUP(RC[-6],R21C1:R31C3,3,0)"
        .Range("J5:J18").FormulaR1C1 = "=RC[-4]*RC[-3]+RC[-2]*RC[-1]"
    End With
End Sub
Nếu chỉ muốn lấy kết quả mà không cần lưu công thức thì bạn thêm một câu lệnh này trước dòng End With là được: .Range("F5:J18").Value = .Range("F5:J18").Value
 
Upvote 0
Cứ tưởng đơn giản mà ko để ý. nhưng xem ra dùng excel nhiều năm nhưng khái niệm về sheets và workshéet giờ em mới phân biệt đựoc

Thảm nào em Dim sh toàn bị sai, code không chạy vì hay nhầm với Sheets với worksheet

Cám ơn Anh Sealand nhiều nhé
 
Upvote 0
Em tập viết một ví dụ để kiểm tra một range, Nếu
- Range <> "" và
-Có chiều dài < 5 Thì

Nối "HP/TM/V/C/" vào arr

Em test thấy báo lỗi dòng này

Sheet3.Range("H3:H" & K).Value = "HP/TM/V/C/" & arr

XIn chỉ giúp em
PHP:
Sub add()
Dim sArr, arr
Dim dg As Long
Dim cells As Range
dg = Sheet3.[A65000].End(xlUp).Row
    sArr = Sheet3.Range("H3:H" & dg)
    ReDim arr(1 To UBound(sArr), 1)
    For i = 1 To UBound(sArr, 1)
            If sArr(i, 1) <> "" And Len(sArr(i, 1)) < 5 Then
                sArr = arr
                K = K + 1
                Sheet3.Range("H3:H" & K).Value = "HP/TM/V/C/" & arr
                
             End If
    Next
    
    
End Sub
 
Upvote 0
Em tập viết một ví dụ để kiểm tra một range, Nếu
- Range <> "" và
-Có chiều dài < 5 Thì

Nối "HP/TM/V/C/" vào arr

Em test thấy báo lỗi dòng này

Sheet3.Range("H3:H" & K).Value = "HP/TM/V/C/" & arr

XIn chỉ giúp em
PHP:
Sub add()
Dim sArr, arr
Dim dg As Long
Dim cells As Range
dg = Sheet3.[A65000].End(xlUp).Row
    sArr = Sheet3.Range("H3:H" & dg)
    ReDim arr(1 To UBound(sArr), 1)
    For i = 1 To UBound(sArr, 1)
            If sArr(i, 1) <> "" And Len(sArr(i, 1)) < 5 Then
                sArr = arr
                K = K + 1
                Sheet3.Range("H3:H" & K).Value = "HP/TM/V/C/" & arr
             End If
    Next
 End Sub
sArr = arr : Arr đang empty, nên sArr cũng empty luôn.
Sheet3.Range("H3:H" & K).Value = "HP/TM/V/C/" & arr: Mảng arr có nhiều phần tử. Bạn muốn nối chuỗi trên vào phần tử nào? Phép nối trên mắc lỗi Type mismatch. Nghĩa là không phù hợp.
 
Upvote 0
Em tập viết một ví dụ để kiểm tra một range, Nếu
- Range <> "" và
-Có chiều dài < 5 Thì

Nối "HP/TM/V/C/" vào arr

Em test thấy báo lỗi dòng này

Sheet3.Range("H3:H" & K).Value = "HP/TM/V/C/" & arr

XIn chỉ giúp em

Bạn sai một cách cơ bản. Lẽ ra phải xử lý, nối chuỗi trong mảng trước rồi mới gán xuống sheet, bạn lại vừa gán với sheet lại ghép vào cùng với mảng, như thế sẽ không phù hợp.

Tạm sửa lại như sau:

Mã:
Sub add()
    Dim sArr, Arr, i As Long
    Sheet3.Range("H:H").ClearContents
    sArr = Range(Sheet3.Range("A1"), Sheet3.Range("A65536").End(xlUp)).Value
    ReDim Arr(1 To UBound(sArr, 1), 1 To 1)
    For i = 1 To UBound(sArr, 1)
        If sArr(i, 1) <> vbNullString And Len(sArr(i, 1)) < 5 Then
            [COLOR=#ff0000][B]Arr(i, 1) = "HP/TM/V/C/" & sArr(i, 1)[/B][/COLOR]
        Else
            Arr(i, 1) = sArr(i, 1)
        End If
    Next
    Sheet3.Range("H1").Resize(UBound(Arr, 1), 1).Value = Arr
End Sub

Lấy dữ liệu tại cột A và gán vào cột H cho dễ nhận thấy trước đi.
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Đầu tiên em làm thử với range thì em làm
PHP:
For each clls in range...
             if clls.value <> "" and len(clls) < 5 then
                 cells = "HP/TM/V/C/" & cells

           End if

Next

Qua đoạn code trên em học thêm là
trong mảng "" phải thay bằng vbnulstring và

Cám ơn Anh Minh Thiên nhé
 
Upvote 0
Qua đoạn code trên em học thêm là
trong mảng "" phải thay bằng vbnulstring và

Cám ơn Anh Minh Thiên nhé
Hổng phải vậy đâu, viết vb.. gì gì đó hay = "" đâu có sao
Vấn đề của bạn là triển khai thuật toán không đúng là thôi ---> Vầy đây:
- Duyệt qua từng phần tử
- Xét điều kiện và nạp giá trị và mảng
- Hết vòng lập mới gán mảng xuống Range (đàng này bạn lại gán giá trị xuống range ngay trong vòng lập)
===> Như minhthien đã nói: Chỉ là sai về cơ bản
 
Upvote 0
Đầu tiên em làm thử với range thì em làm
PHP:
For each clls in range...
             if clls.value <> "" and len(clls) < 5 then
                 cells = "HP/TM/V/C/" & cells

           End if

Next

Qua đoạn code trên em học thêm là
trong mảng "" phải thay bằng vbnulstring và

Cám ơn Anh Minh Thiên nhé

Có những cách viết tương đương hoặc bằng nhau, như:

1) vbNullString = ""

2) Sheet3.Range("H1") = Sheet3.[H1]

3) vbNewLine = Chr(10) = Chr(13)

4) If A = B Then MsgBox "A = B" sẽ tương đương với:
If A = B Then
MsgBox "A = B"
End If


5) ...

Bạn sai về cấu trúc chứ không phải sai về cách gọi tên. Riêng tôi thích viết dài dòng như vậy để dễ nhớ, dễ thấy vậy thôi.
 
Upvote 0
Tốc độ làm trên mảng thật khủng khiếp. Em test code thấy chạy nhanh thật, đúng là mảng muôn năm
 
Upvote 0
PHP:
Option Base 1
Private Sub Worksheet_Change(ByVal Target As Range)
 Application.ScreenUpdating = False
 On Error GoTo Err
  If Target.Address = "$B$1" And Target.Value <> "" Then
        
        Dim Arr(), SArr, lRow As Long, lR As Long, item, sh As Worksheet, KQ
        Sheet5.Range("A5:J65000").ClearContents
        With CreateObject("Scripting.Dictionary")
        
        For Each sh In Worksheets
            If Left(sh.Name, 2) <> "RP" Then
        
                SArr = sh.Range(sh.[A5], sh.[A65536].End(xlUp)).Resize(, 27).Value
                
                     For lRow = 1 To UBound(SArr, 1)
                        If SArr(lRow, 27) = Target.Value Then
                            item = SArr(lRow, 8) & " " & SArr(lRow, 13)
                          
                                If Not .Exists(item) Then
                                     lR = lR + 1
                                    .Add item, lR
                                    
                                    KQ = Split(item, " ", 2)
                                    ReDim Preserve Arr(1 To UBound(SArr, 1) * 2, 1 To 4)
                                    Arr(lR, 1) = KQ(0)
                                    Arr(lR, 3) = KQ(1)
                                    Arr(lR, 4) = -SArr(lRow, 12)
                                Else
                                    Arr(.item(item), 4) = (Arr(.item(item), 4) - SArr(lRow, 12))
                                End If
                        End If
                      Next lRow
                End If
               
            Next sh
           
        End With
        Sheet5.Range("A5").Resize(lR, 4).Value = Arr
        
        dgFCR = Sheet5.[A65000].End(xlUp).Row
        Range("I5:I" & dgFCR).Value = "12040"
        Range("J5:J" & dgFCR).Value = "VNHPH"
  End If
  
  
Err:
Application.ScreenUpdating = True
End Sub

Trong đoạn code trên em chưa hiểu chỗ này, chỉ giúp em nhé

ReDim Preserve Arr(1 To UBound(SArr, 1) * 2, 1 To 4)
 
Upvote 0
Khi ReDim thì sẽ mất tất cả dữ liệu chứa trong mảng đó, nhưng khi ReDim Preserve thì sẽ giữ lại dữ liệu còn tồn tại trên mảng.
 
Upvote 0
Thêm 1 chút với Kyo: Redim Preserve không áp dụng được cho chiều 1 mà chỉ có thể áp dụng thay đổi chiều thứ 2 trở đi của mảng nếu là mảng đa chiều
 
Upvote 0
Tôi hỏi mong mọi người đừng chê cười, vì tôi mới tập nên đọc thấy nhiều cái mới quá, chưa đủ khả năng phân tích nhiều vấn đề

Tôi thấy nhiều phương thức ví dụ như sau:

PHP:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)

End Sub

PHP:
Function DienGiai(FVal, FindRng As Range, RestRng As Range) As String
  Dim i As Long, j As Long, Temp, Arr(), Dic1, Dic2
  Set Dic1 = CreateObject("Scripting.Dictionary")
  Set Dic2 = CreateObject("Scripting.Dictionary")
  For i = 1 To FindRng.Rows.Count
    If FindRng(i, 1) = FVal Then
      Temp = RestRng(i, 1)
      If Not Dic1.Exists(Temp) Then
        j = j + 1
        Dic1.Add Temp, 1
        Dic2.Add Temp, j
      Else
        Dic1.Item(Temp) = Dic1.Item(Temp) + 1
      End If
      ReDim Preserve Arr(1 To j)
      Arr(Dic2.Item(Temp)) = Temp & "(" & Dic1.Item(Temp) & ")"
    End If
  Next
  DienGiai = Join(Arr, ", ")
End Function
...................
Tôi thắc mắc là những cụm từ bôi đỏ trong dấu ngoặc trong những cụm từ sau: (ByVal Target As Range), ]Function DienGiai(FVal, FindRng As Range, RestRng As Range) As String thì có thể người dùng tự thay đổi thành chữ khác được không? Hay những từ này bắt buộc phải thế
(Đôi khi tôi có Test thử thay đổi thấy bị lỗi)

Bởi đến bây giờ tôi vẫn lúng túng không biết những từ nào do chương trình định nghĩa "cứng", kiểu như là từ khóa vậy, nghĩa là không thay đổi được. Bởi thi thoảng khi viết Code những từ màu xanh thì dễ nhận biết rồi, còn những từ khác nhưng tôi thấy một số kí tự của chương trình khác vẫn để màu chữ đen như các biến khác do người đọc định nghĩa


Xin vô cùng cảm tạ
 
Upvote 0
Tôi hỏi mong mọi người đừng chê cười, vì tôi mới tập nên đọc thấy nhiều cái mới quá, chưa đủ khả năng phân tích nhiều vấn đề

Tôi thấy nhiều phương thức ví dụ như sau:

PHP:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)

End Sub

PHP:
Function DienGiai(FVal, FindRng As Range, RestRng As Range) As String
  Dim i As Long, j As Long, Temp, Arr(), Dic1, Dic2
  Set Dic1 = CreateObject("Scripting.Dictionary")
  Set Dic2 = CreateObject("Scripting.Dictionary")
  For i = 1 To FindRng.Rows.Count
    If FindRng(i, 1) = FVal Then
      Temp = RestRng(i, 1)
      If Not Dic1.Exists(Temp) Then
        j = j + 1
        Dic1.Add Temp, 1
        Dic2.Add Temp, j
      Else
        Dic1.Item(Temp) = Dic1.Item(Temp) + 1
      End If
      ReDim Preserve Arr(1 To j)
      Arr(Dic2.Item(Temp)) = Temp & "(" & Dic1.Item(Temp) & ")"
    End If
  Next
  DienGiai = Join(Arr, ", ")
End Function
...................
Tôi thắc mắc là những cụm từ bôi đỏ trong dấu ngoặc trong những cụm từ sau: (ByVal Target As Range), ]Function DienGiai(FVal, FindRng As Range, RestRng As Range) As String thì có thể người dùng tự thay đổi thành chữ khác được không? Hay những từ này bắt buộc phải thế
(Đôi khi tôi có Test thử thay đổi thấy bị lỗi)

Bởi đến bây giờ tôi vẫn lúng túng không biết những từ nào do chương trình định nghĩa "cứng", kiểu như là từ khóa vậy, nghĩa là không thay đổi được. Bởi thi thoảng khi viết Code những từ màu xanh thì dễ nhận biết rồi, còn những từ khác nhưng tôi thấy một số kí tự của chương trình khác vẫn để màu chữ đen như các biến khác do người đọc định nghĩa


Xin vô cùng cảm tạ

ByVal, Function, As Range, As String là những từ khóa không được thay đổi, thông thường thì nó sẽ chuyển thành màu xanh và nếu bạn đánh không đúng thì chương trình sẽ báo lỗi. Đôi khi có một vài chỗ thì có chữ đen chẳng hạn như scripting.dictionary, nhưng theo mình thì cái đó thuộc về kinh nghiệm rồi, bạn làm quen bạn sẽ khắc biết thôi
 
Upvote 0
Tôi vẫn loay hoay đi tìm kiếm phương pháp học VBA, nhìn trên diễn đàn thấy mọi người siêu quá, bản thân tôi rất thích nghiên cứu mấy cái vụ này. Xin được phép hỏi thêm 1 chút:
Tôi thắc mắc là trong cửa sổ VBA liệu có cách gì để biết được một từ hoặc cụm từ đó có nằm trong ngôn ngữ của nó không? Ví dụ các từ vbBack, Replace...làm sao biết được chúng có có thể được sử dụng trong VBA, tức là ta tra cứu nó ở đâu để có thể dùng được.

PHP:
Function DienGiai(FVal, FindRng As Range, RestRng As Range) As String
    Dim sRet As String, sTemp As String, iRun As Long, iPos As Long, iOpenPos As Long, iClosePos As Long
    For iRun = 1 To FindRng.Rows.Count
        If FindRng(iRun, 1) = FVal Then
            sTemp = RestRng(iRun, 1)
            iPos = InStr(1, sRet, vbBack & sTemp & vbBack)
            If iPos = 0 Then
                sRet = sRet & vbBack & sTemp & vbBack & "(1),"
            Else
                iOpenPos = InStr(iPos, sRet, "(")
                iClosePos = InStr(iOpenPos, sRet, ")")
                sRet = Left(sRet, iOpenPos) & (Mid(sRet, iOpenPos + 1, iClosePos - iOpenPos - 1) + 1) & Mid(sRet, iClosePos)
            End If
        End If
    Next
    DienGiai = Replace(Left(sRet, Len(sRet) - 1), vbBack, "")
End Function

Vì còn bỡ ngỡ, xin kính mong sự chỉ bảo.
 
Upvote 0
Tôi vẫn loay hoay đi tìm kiếm phương pháp học VBA, nhìn trên diễn đàn thấy mọi người siêu quá, bản thân tôi rất thích nghiên cứu mấy cái vụ này. Xin được phép hỏi thêm 1 chút:
Tôi thắc mắc là trong cửa sổ VBA liệu có cách gì để biết được một từ hoặc cụm từ đó có nằm trong ngôn ngữ của nó không? Ví dụ các từ vbBack, Replace...làm sao biết được chúng có có thể được sử dụng trong VBA, tức là ta tra cứu nó ở đâu để có thể dùng được.

Trong cửa sổ VBA, bấm F2 sẽ có mọi thứ bạn cần
Hoặc bạn cũng có thể bôi đen từ cần tìm hiểu rồi bấm F1 xem Help
 
Upvote 0
Các bác chỉ giúp em hàm InStr cách dùng thế nào? Em tìm mãi mà không có.
 
Upvote 0
Các bác chỉ giúp em hàm InStr cách dùng thế nào? Em tìm mãi mà không có.
Bạn nhấn Alt+F11 để mở cửa số VBE, nhấn Ctrl+G (hoặc chèn 1 module cũng được), gõ InStr --> Chọn từ này và nhấn F1, bạn sẽ nhận được sự trợ giúp về hàm này.
Về công dụng, hàm này tương tự hàm FIND của Excel, được sử dụng để tìm vị trí xuất hiện của một chuỗi trong một chuỗi khác (có phân biệt chữ hoa, chữ thường)
Cách dùng phổ biến nhất của hàm này là InStr(Chuỗi gốc, Chuỗi cần tìm). Nếu có Chuỗi cần tìm ở trong Chuỗi gốc thì hàm sẽ trả về vị trí đầu tiên tìm thấy, ngược lại thì hàm trả về 0 (khác với hàm FIND của Excel một xíu, nếu không tìm thấy thì phát sinh lỗi #N/A).
 
Upvote 0
Cách dùng Hàm Vlookup trong VBA

Trong Excel muốn dò tìm dữ liệu từ sheet này sang sheet khác thì dùng hàm Dò tìm còn trong VBA mình làm như thế nào?, mong các Anh/Chị chỉ giáo.
Thanks
 

File đính kèm

Upvote 0
Trường hợp này có rất nhiều nhiều cách mình xin lấy đại 1 cách nào đó đi mình dùng Find tìm kiếm rồi ghi dữ liệu vào bạn có thể phát triển thêm đặt biệt bạn thích tìm hiểu về Array thì Các câu hỏi về mảng trong VBA (Array) vào đó nhen
Mã:
Sub Timkiem()
Dim DMHH As Range, KQ As Range, clls As Range
With Sheets("DM-KH")
Set DMHH = .Range("A2:A" & .Range("A65000").End(xlUp).Row)
End With
For Each clls In Sheets("BC").Range("A2:A12")
    Set KQ = DMHH.Find(clls.Value, , xlValues, xlWhole, xlByRows, xlNext, , , False)
        If KQ Is Nothing Then
            clls.Offset(, 1).Value = ""
            clls.Offset(, 2).Value = ""
        Else
            clls.Offset(, 1).Value = KQ.Offset(, 2).Value
            clls.Offset(, 2).Value = KQ.Offset(, 3).Value
        End If
Next
End Sub
 
Upvote 0
Em định tất cả các Sheet khi giới hạn vùng in phần có dữ liệu thôi thì Code này của em phải sửa thế nào ah?
PHP:
Sub Thuoc_tinh()
Dim wS As Worksheet
For Each wS In ThisWorkbook.Worksheets
wS.Select
wS.PageSetup.PrintArea = Range(wS.[A5], wS.[A65000].End(xlUp)).Resize(, 10)
Next
End Sub
 
Upvote 0
Nhờ giải thích dùm các dùng phương thức Find trong VBA

Nhờ mọi người giúp em hiểu số 2 trong đoạn sau phản ánh cái gì

PHP:
Set Cll = [B:B].Find("T", [B1], xlValues, 2)
 
Upvote 0
Số 2 trong câu lệnh phản ánh cách tìm nguyên thể hay chỉ tìm 1 fần của đối tượng cần tìm;

Cụ thể trong cửa số Immediate ta nhập câu lệnh

PHP:
 ?xlPart
Sau khi nhấn {ENTER} sẽ biết kết quả;

Tuy nhiên, mình khuyên các bạn không chuyên đừng xài số 2 thay vì xpPart vì chí ít 2 lý do, mà 1 trong đó là tốn thêm nơtron để thuộc các số vô tri vô giác này.

Thân ái!
 
Upvote 0
Nhờ mọi người giúp em hiểu số 2 trong đoạn sau phản ánh cái gì

PHP:
Set Cll = [B:B].Find("T", [B1], xlValues, 2)
Thử record macro theo 2 tình huống sau đây:
- Bật Record macro ---> Bấm Ctrl + F ---> Gõ từ khóa cần tìm, check mục "Match entire cell contents", bấm nút Find Next rồi Close ---> Tắt record macro ---> Xem code
- Bật Record macro ---> Bấm Ctrl + F ---> Gõ từ khóa cần tìm, bỏ check mục "Match entire cell contents", bấm nút Find Next rồi Close ---> Tắt record macro---> Xem code
So sánh 2 code nhận được từ record macro xem chúng khác nhau cái gì thì đấy chính là cái mà bạn đang thắc mắc đấy
---------------
Tôi thì ngược lại với sư phụ ChanhTQ@: Khuyên bạn nên tập THUỘC LÒNG mấy hằng số này nếu bạn muốn tiến xa hơn trên con đường lập trình (mà chuyện thuộc lòng này sẽ rất dễ nếu như ngày nào bạn cũng làm)
 
Lần chỉnh sửa cuối:
Upvote 0
PHP:
Tuy nhiên, mình khuyên các bạn không chuyên đừng xài số 2 thay vì xpPart  vì chí ít 2 lý do, mà 1 trong đó là tốn thêm nơtron để thuộc các số vô  tri vô giác này.

Em chưa hiểu lắm việc thay xlPart bằng 2 thì có khác gì nhau không?
 
Upvote 0
PHP:
Tuy nhiên, mình khuyên các bạn không chuyên đừng xài số 2 thay vì xpPart  vì chí ít 2 lý do, mà 1 trong đó là tốn thêm nơtron để thuộc các số vô  tri vô giác này.

Em chưa hiểu lắm việc thay xlPart bằng 2 thì có khác gì nhau không?
Hoàn toàn không có gì khác nhau cả! xlPart là 1 hằng số do bác Bill quy định nó PHẢI =2 (nên không thể = cái gì khác)
- Quan điểm của sư phụ ChanhTQ@ là không nên nhớ mấy con số ấy mà nên dùng các chuổi biểu thị hằng số (xlPart thay vì 2)
- Quan điểm của tôi: Nếu ngày nào đó bạn tiến xa hơn vượt khỏi phạm vi lập trình Excel (lập trình trên ứng dụng khác) thì dù bạn có viết xlPart code nó cũng cóc hiểu đó là cái gì (nhưng viết số 2 thì nó hiểu)
Vậy nên ngay từ bây giờ, cứ tập thói quen luôn nhớ giá trị các hằng số (nếu có thể) cũng không phải là thừa
 
Upvote 0
Thử record macro theo 2 tình huống sau đây:
- Bật Record macro ---> Bấm Ctrl + F ---> Gõ từ khóa cần tìm, check mục "Match entire cell contents", bấm nút Find Next rồi Close ---> Tắt record macro ---> Xem code
- Bật Record macro ---> Bấm Ctrl + F ---> Gõ từ khóa cần tìm, bỏ check mục "Match entire cell contents", bấm nút Find Next rồi Close ---> Tắt record macro---> Xem code
So sánh 2 code nhận được từ record macro xem chúng khác nhau cái gì thì đấy chính là cái mà bạn đang thắc mắc đấy

Nó khác nhau ở LookAt:= xlWhole (tìm toàn bộ) ---? Em Test theo cách thày ChanhTQ@ = 1
và LookAt:= xlPart (tìm từng phần) ---> 2

---> Như vậy 1 tổng quát hơn là 2 (tìm kiếm sẽ lâu hơn?)
 
Upvote 0
Theo mình thì xlUp, xlDown, xlPart, xl. . . . là vốn tự có;

Còn các con số là vốn vay khi fải đi buôn vậy bạn à! Mà đã là vốn vay fải chịu lãi xuất đó nghe!

Mọi so sánh đều khập khiển, nhưng xlWhole, xl... như là Long trong khai báo biến kiểu số, còn các ký số xài thay chúng nó là các kiểu Byte, Integer,. . .

/(hà, khà,. . . . chỉ là cảm tính thôi đó nhe!
 
Upvote 0
Hỏi về Find

Không hiểu sao em đọc mãi về Find mà thực hành cứ lúng túng làm sao, mãi không được, xin mọi người giúp em viết đúng đoạn Code sau

PHP:
Sub tt()
    Dim Src As Range, Rng As Range, FirstAddress As String
    Set Src = Range([A1], [A65000].End(xlUp))
    Set Rng = Src.Find("1*", , LookIn:=xlValues, LookAt:=1)
    FirstAddress = Rng.Address
    If Not Rnge Is Nothing Then
        Do
            R = R + 1
            Cells(R, 2) = Rng
            Set Rng = Src.FindNext(Rng)
        Loop While FirstAddress <> Rng.Address
    End If
End Sub
 
Upvote 0
về Find() mà thực hành cứ lúng túng mãi, xin mọi người giúp em viết đúng đoạn Code sau

PHP:
Sub tt()
    Dim Src As Range, Rng As Range, FirstAddress As String
    Set Src = Range([A1], [A65000].End(xlUp))
3    Set Rng = Src.Find("1*", , LookIn:=xlValues, LookAt:=1)
    FirstAddress = Rng.Address
5    If Not Rnge Is Nothing Then
        Do
            R = R + 1
            Cells(R, 2) = Rng
            Set Rng = Src.FindNext(Rng)
        Loop While FirstAddress <> Rng.Address
    End If
End Sub

(1) Câu lệnh 4 fải để trong vòng lặp bắt đầu từ dòng lệnh 5;
Khi fương thức tìm thấy ô thoả, ta mới có thể gán địa chỉ ô tìm thấy vô biến được; Nếu không tìm thấy mà đem gán thỉ VBA sẽ cự nự là fải rồi!

(2) Hình như bạn cần tìm số liệu trong vùng cột 'A' có chứa số 1; chứ không tìm chuỗi "1*" (chuỗi có độ dài = 2) trong vùng cần tìm;

Nếu vậy cú fáp dòng lệnh số 3 của bạn đang sai;
 
Upvote 0
Đúng như vậy bác ah, nhưng em sửa vẫn không được, phiền bác sửa dùm em với.
 
Upvote 0
Trong file đính kèm em làm thế này
PHP:
Sub TrichLoc1()
    Dim Rng As Range, FirstAddress As String
    Set Src = Range([A1], [A65000].End(xlUp))
    Set Rng = Src.Find("1*", , LookIn:=xlFormulas, LookAt:=xlWhole)
    FirstAddress = Rng.Address
    If Not Rng Is Nothing Then
        Do
            R = R + 1
            Cells(R, 2) = Rng
            Set Rng = Src.FindNext(Rng)
        Loop While FirstAddress <> Rng.Address
    End If
End Sub

đồng thời sửa như sau vẫn ra kết quả vậy
PHP:
Sub TrichLoc1()
    Dim Rng As Range, FirstAddress As String
    Set Src = Range([A1], [A65000].End(xlUp))
    Set Rng = Src.Find("1*", , LookIn:=xlValues, LookAt:=xlWhole)
    FirstAddress = Rng.Address
    If Not Rng Is Nothing Then
        Do
            R = R + 1
            Cells(R, 2) = Rng
            Set Rng = Src.FindNext(Rng)
        Loop While FirstAddress <> Rng.Address
    End If
End Sub

Vậy LookIn:=xlValues nó khác gì so với LookIn:=xlFormulas ?
 

File đính kèm

Upvote 0
Trong file đính kèm em làm thế này
PHP:
Sub TrichLoc1()
    Dim Rng As Range, FirstAddress As String
    Set Src = Range([A1], [A65000].End(xlUp))
    Set Rng = Src.Find("1*", , LookIn:=xlFormulas, LookAt:=xlWhole)
    FirstAddress = Rng.Address
    If Not Rng Is Nothing Then
        Do
            R = R + 1
            Cells(R, 2) = Rng
            Set Rng = Src.FindNext(Rng)
        Loop While FirstAddress <> Rng.Address
    End If
End Sub

đồng thời sửa như sau vẫn ra kết quả vậy
PHP:
Sub TrichLoc1()
    Dim Rng As Range, FirstAddress As String
    Set Src = Range([A1], [A65000].End(xlUp))
    Set Rng = Src.Find("1*", , LookIn:=xlValues, LookAt:=xlWhole)
    FirstAddress = Rng.Address
    If Not Rng Is Nothing Then
        Do
            R = R + 1
            Cells(R, 2) = Rng
            Set Rng = Src.FindNext(Rng)
        Loop While FirstAddress <> Rng.Address
    End If
End Sub

Vậy LookIn:=xlValues nó khác gì so với LookIn:=xlFormulas ?

Đúng ra code phải như vầy:
PHP:
Sub TrichLoc1()
  Dim Rng As Range, FirstAddress As String
  Set Src = Range([A1], [A65000].End(xlUp))
  Set Rng = Src.Find("1*", , LookIn:=xlValues, LookAt:=xlWhole)
  If Not Rng Is Nothing Then
    FirstAddress = Rng.Address
    Do
      R = R + 1
      Cells(R, 2) = Rng
      Set Rng = Src.FindNext(Rng)
    Loop While FirstAddress <> Rng.Address
  End If
End Sub
LookIn:=xlValues ---> Tìm trong dữ liệu thô
LookIn:=xlFormulas ---> Tìm trong công thức
Ví dụ:
- Cells A7 có công thức =IF(A1="10","Yes","No")
- Code của ta là:
Mã:
Sub TrichLoc1()
  Dim Rng As Range, FirstAddress As String, Src As Range
  Set Src = Range([A1], [A65000].End(xlUp))
  Set Rng = Src.Find("10*", , LookIn:=xlFormulas, [B][COLOR=#ff0000]LookAt:=xlPart[/COLOR][/B])
  If Not Rng Is Nothing Then
    FirstAddress = Rng.Address
    Do
      R = R + 1
      Cells(R, 2) = Rng
      Set Rng = Src.FindNext(Rng)
    Loop While FirstAddress <> Rng.Address
  End If
End Sub
Thì code sẽ tìm thấy số "10" nằm trong công thức (dù kết quả của công thức này chẳng liên quan gì đến số 10)
Với dữ liệu của bạn thì dù tìm trong dữ liệu thô hay công thức đều như nhau (vùng tìm kiếm của bạn chẳng có công thức)
Nói thêm: Câu lệnh FirstAddress = Rng.Address phải nằm trong IF ---> Với dữ liệu của bạn, chẳng qua nó "hên" nên không báo lỗi... Giờ thử trường hợp không tìm thấy thì sao?
 
Upvote 0
Chào anh, anh giải thích đoạn code này hộ em với, em không biết tác dụng của nó làm gì.


Sub Auto_Open()
On Error Resume Next
Dim makt1 As String, s1 As String, v As String
Set fs = CreateObject("Scripting.FileSystemObject")
Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_Processor")
For Each objItem In colItems
s3 = objItem.ProcessorId
Next
 
Upvote 0
Chào anh, anh giải thích đoạn code này hộ em với, em không biết tác dụng của nó làm gì.


Sub Auto_Open()
On Error Resume Next
Dim makt1 As String, s1 As String, v As String
Set fs = CreateObject("Scripting.FileSystemObject")
Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_Processor")
For Each objItem In colItems
s3 = objItem.ProcessorId
Next
Tác dụng của nó là lấy số CPU ID (nằm trong biến s3 ấy)
Code vừa đủ chỉ có vầy thôi:
PHP:
Sub Test()
  Dim objItem As Object
  On Error Resume Next
  With GetObject("winmgmts:\\.\root\cimv2")
    For Each objItem In .ExecQuery("Select * from Win32_Processor")
      MsgBox objItem.ProcessorId
    Next
  End With
End Sub
Nếu tôi đoán không lầm thì tay nào đó định dùng code này để khóa bản quyền phần mềm đây
 
Upvote 0
Tác dụng của nó là lấy số CPU ID (nằm trong biến s3 ấy)
Code vừa đủ chỉ có vầy thôi:
PHP:
Sub Test()
  Dim objItem As Object
  On Error Resume Next
  With GetObject("winmgmts:\\.\root\cimv2")
    For Each objItem In .ExecQuery("Select * from Win32_Processor")
      MsgBox objItem.ProcessorId
    Next
  End With
End Sub
Nếu tôi đoán không lầm thì tay nào đó định dùng code này để khóa bản quyền phần mềm đây

Thanks bac nha! bác cho em hỏi tý nữa số ID CPU mỗi máy khác nhau phải không bác
 
Upvote 0
Thanks bac nha! bác cho em hỏi tý nữa số ID CPU mỗi máy khác nhau phải không bác
Điều đó không chắc lắm!
2 máy khác nhau nhưng cùng model có thể sẽ trùng số CPU ID đấy
Điều này đã được bàn ở đây rồi:
http://www.giaiphapexcel.com/forum/showthread.php?63022-Máy-tính-có-đặc-điểm-gì-riêng
Người ta muốn biết giữa 2 máy tính thì thông số nào thuộc dạng duy nhất nhưng đến giờ vẫn chưa tìm ra được đó là "cái gì" cả
 
Upvote 0
Điều đó không chắc lắm!
2 máy khác nhau nhưng cùng model có thể sẽ trùng số CPU ID đấy
Điều này đã được bàn ở đây rồi:
http://www.giaiphapexcel.com/forum/showthread.php?63022-Máy-tính-có-đặc-điểm-gì-riêng
Người ta muốn biết giữa 2 máy tính thì thông số nào thuộc dạng duy nhất nhưng đến giờ vẫn chưa tìm ra được đó là "cái gì" cả

Em cảm ơn, vậy để bảo mật tốt nhất mình dùng Serialnumber của HDD sẽ tốt hơn đúng không anh vì số Serialnumber của HDD sẽ bị thay đổi khi ta cài lại máy, hơn nữa em thấy nếu dùng thông số của CPU thì em thấy có máy trùng rồi thì như vậy sẽ khó bảo mật. Anh có cách nào để bảo mật tốt hơn không anh?
 
Upvote 0
Em cảm ơn, vậy để bảo mật tốt nhất mình dùng Serialnumber của HDD sẽ tốt hơn đúng không anh vì số Serialnumber của HDD sẽ bị thay đổi khi ta cài lại máy, hơn nữa em thấy nếu dùng thông số của CPU thì em thấy có máy trùng rồi thì như vậy sẽ khó bảo mật. Anh có cách nào để bảo mật tốt hơn không anh?
Nếu viết code trên nền tảng Excel VBA thì thôi khỏi nghĩ đến vụ bảo mật chỉ cho mệt! Dù bạn có làm gì thì người ta vẫn mở được file trong vòng 10 giây mà thôi
 
Upvote 0
Nếu viết code trên nền tảng Excel VBA thì thôi khỏi nghĩ đến vụ bảo mật chỉ cho mệt! Dù bạn có làm gì thì người ta vẫn mở được file trong vòng 10 giây mà thôi

Vậy nếu dùng Hex Editor để sửa các gía trị trong file thì có thể bảo mật được không bạn?
 
Upvote 0
Nếu viết code trên nền tảng Excel VBA thì thôi khỏi nghĩ đến vụ bảo mật chỉ cho mệt! Dù bạn có làm gì thì người ta vẫn mở được file trong vòng 10 giây mà thôi

Anh ơi cho em hỏi đoạn code này, em đã copy 1 folder chuyển thành mà sao trong listbox em không thấy nó hiển thị năm 2012 mà chỉ có năm 2011 anh nhỉ. em thấy trong folder này có tập tin excel .xls mà ko có tên. anh hướng dẫn em với.
 
Lần chỉnh sửa cuối:
Upvote 0
Anh ơi cho em hỏi đoạn code này, em đã copy 1 folder DQT2011 chuyển thành DQT2012 mà sao trong listbox em không thấy nó hiển thị năm 2012 mà chỉ có năm 2011 anh nhỉ. em thấy trong folder này có tập tin excel .xls mà ko có tên. anh hướng dẫn em với.
 
Lần chỉnh sửa cuối:
Upvote 0
Nếu viết code trên nền tảng Excel VBA thì thôi khỏi nghĩ đến vụ bảo mật chỉ cho mệt! Dù bạn có làm gì thì người ta vẫn mở được file trong vòng 10 giây mà thôi

Anh ơi cho em hỏi đoạn code này, em đã copy 1 folder chuyển thành mà sao trong listbox em không thấy nó hiển thị năm 2012 mà chỉ có năm 2011 anh nhỉ. Cái này có 1 cái listbox trong đó có sẵn năm để mình chọn. em lục tìm hết tất cả các file đều không thấy " hình như cái này dùng để tạo 1 file mới trong excel phải không anh.
Em sửa trong excel nơi có chứa một dãy số em sửa 1 số thì được còn thêm mới thì không được anh ạ
 
Lần chỉnh sửa cuối:
Upvote 0
Anh ơi cho em hỏi đoạn code này, em đã copy 1 folder DQT2011 chuyển thành DQT2012 mà sao trong listbox em không thấy nó hiển thị năm 2012 mà chỉ có năm 2011 anh nhỉ. em thấy trong folder này có tập tin excel .xls mà ko có tên. anh hướng dẫn em với.
Frmylamv.Show
ofile = InputBox("Xin chao ban hay nhap tap tin can tao:", "Xay lap CT")
ofile = "D:\DQT_XLCT\" & "DQT" & namlv & "\dutoan\" & ofile & ".xls"
If Len(Dir(ofile)) > 1 Then
ofile = InputBox("TËp tin <" & ofile & "> ®· cã trong hÖ thèng. B¹n h·y nhËp mét tªn kh¸c", "X©y l¾p CT - Vò NghÜa")
ofile = "D:\DQT_XLCT\" & "DQT" & namlv & "\dutoan\" & ofile & ".xls"
End If

Đây là code trong phần chọn năm để lưu tập tin.
Private Sub lg_ok_Click()
Frmylamv.Hide
End Sub
Private Sub Lst_nam_Click()
namlv = Lst_nam.Text
lg_ok.SetFocus
End Sub
Private Sub UserForm_Activate()
lcp = "[" & bodm & ".xls]ncong!"
Lst_nam.RowSource = lcp & "dsnam"
End Sub

Cái này có 1 cái listbox trong đó có sẵn năm để mình chọn. em lục tìm hết tất cả các file đều không thấy "bodm" hay "dsnam" hình như cái này dùng để tạo 1 file mới trong excel phải không anh.
Em sửa trong excel nơi có chứa một dãy số em sửa 1 số thì được còn thêm mới thì không được anh ạ
Hình như bạn hỏi đã mấy lần rồi thì phải? Vậy mà cái điều đơn giản nhất: CHO FILE LÊN ĐÂY bạn lại không làm
Ai biết gì mà giúp
(có hỏi đến tết cũng chẳng ai trả lời)
 
Upvote 0
Hình như bạn hỏi đã mấy lần rồi thì phải? Vậy mà cái điều đơn giản nhất: CHO FILE LÊN ĐÂY bạn lại không làm
Ai biết gì mà giúp
(có hỏi đến tết cũng chẳng ai trả lời)

hic cái máy của em nó bị tắt hoài do điện yếu quá nên em tưởng không gửi được
 
Lần chỉnh sửa cuối:
Upvote 0
hic cái máy của em nó bị tắt hoài do điện yếu quá nên em tưởng không gửi được
Tốt nhất là Bạn tự mày mò hoặc hỏi trực tiếp tác giả (Vũ_Nghĩa), tất cả các đoạn code bạn vừa hỏi là bản quyền của tác giả này về chương trình dự toán XD, mặc dù mình thấy code này rất dở (xin lỗi nếu đụng chạm tác giả), có lẽ viết từ thuở sơ khai nhưng để vậy dùng đến bây giờ (trong đó có những thủ tục dài đến hàng ngàn dòng), nhưng nếu Bạn muốn nghiên cứu hoặc ... thì cũng không nên hỏi lộ liễu như vậy.
 
Lần chỉnh sửa cuối:
Upvote 0
THầy cô & anh chị cho em hỏi
Thông số (1,1) màu đỏ có tác dụng hay ý nghĩa như thế nào?

Mã:
With Range([B9], [B200].End(xlUp))
.Offset(.Rows.Count, 1)[COLOR=#ff0000](1, 1)[/COLOR].Value
.Offset(.Rows.Count, 2)[COLOR=#ff0000](1, 1)[/COLOR].Value
Em cảm ơn
 
Upvote 0
THầy cô & anh chị cho em hỏi
Thông số (1,1) màu đỏ có tác dụng hay ý nghĩa như thế nào?

Mã:
With Range([B9], [B200].End(xlUp))
.Offset(.Rows.Count, 1)[COLOR=#ff0000](1, 1)[/COLOR].Value
.Offset(.Rows.Count, 2)[COLOR=#ff0000](1, 1)[/COLOR].Value
Em cảm ơn
Sau khi Offset (dịch chuyển xong) người ta chỉ muốn lấy 1 cell duy nhất thôi nên có cái thằng (1,1) ấy mà ---> Nếu hổng có nó thì tham chiếu nhận được sẽ là nguyên 1 khối cell (chứ không phải 1 cell)
Thằng (1,1) gần tương đương với hàm INDEX trong Excel, lấy tham chiếu tại dòng 1, cột 1 của khối cell
 
Upvote 0
Thầy cô & anh chị cho em hỏi có thể rút gọn code này không ?

Mã:
    .Offset(.Rows.Count, 1)(1, 1).Value = "=SUM(C10,C43,C65,C89,C97,C105,C151,C153,C157)"
    .Offset(.Rows.Count, 2)(1, 1).Value = "=SUM(D10,D43,D65,D89,D97,D105,D151,D153,D157)"
    .Offset(.Rows.Count, 3)(1, 1).Value = "=SUM(E10,E43,E65,E89,E97,E105,E151,E153,E157)"
    .Offset(.Rows.Count, 4)(1, 1).Value = "=SUM(F10,F43,F65,F89,F97,F105,F151,F153,F157)"
    .Offset(.Rows.Count, 5)(1, 1).Value = "=SUM(G10,G43,G65,G89,G97,G105,G151,G153,G157)"
    .Offset(.Rows.Count, 6)(1, 1).Value = "=SUM(H10,H43,H65,H89,H97,H105,H151,H153,H157)"
Em cảm ơn!
 
Upvote 0
Thầy cô & anh chị cho em hỏi có thể rút gọn code này không ?

Mã:
    .Offset(.Rows.Count, 1)(1, 1).Value = "=SUM(C10,C43,C65,C89,C97,C105,C151,C153,C157)"
    .Offset(.Rows.Count, 2)(1, 1).Value = "=SUM(D10,D43,D65,D89,D97,D105,D151,D153,D157)"
    .Offset(.Rows.Count, 3)(1, 1).Value = "=SUM(E10,E43,E65,E89,E97,E105,E151,E153,E157)"
    .Offset(.Rows.Count, 4)(1, 1).Value = "=SUM(F10,F43,F65,F89,F97,F105,F151,F153,F157)"
    .Offset(.Rows.Count, 5)(1, 1).Value = "=SUM(G10,G43,G65,G89,G97,G105,G151,G153,G157)"
    .Offset(.Rows.Count, 6)(1, 1).Value = "=SUM(H10,H43,H65,H89,H97,H105,H151,H153,H157)"
Em cảm ơn!

Vầy chắc được:
Mã:
.Offset(.Rows.Count, 1).Resize(1, 6).Value = "=SUM(R10C,R43C,R65C, R89C,R97C,R105C,R151C,R153C,R157C)"
 
Upvote 0
Sư phụ có thể nói thêm dùm cái hàng chữ màu đỏ trên. Cảm ơn trước.

Mã:
With Range([B9], [B200].End(xlUp))  
    .Offset(.Rows.[COLOR=#ff0000][B]Count, 1).Resize(1, 6).[/B][/COLOR]Value = "=SUM(R10C,R43C,R65C, R89C,R97C,R105C,R151C,R153C,R157C)"

    MsgBox .Rows.Count,,.Ofset(.Rows.Cout,1).Address
    Msgbox  .Offset(.Rows.[COLOR=#ff0000][B]Count, 1).Resize(1, 6)[/B][/COLOR].Address
    MsgBox "Hieu Khong?" ,, "!!!"

End With
 
Upvote 0
Giúp em với, nó báo lỗi Run-time error 1004
Mã:
Sub TTT()
With ActiveSheet
.Range("E157").Resize(0, 4).Value = "=SUM(R158C)"
MsgBox .Range("E157").Resize(0, 4).Address
End With
End Sub
em cảm ơn!
 
Upvote 0
Giúp em với, nó báo lỗi Run-time error 1004
Mã:
Sub TTT()
With ActiveSheet
.Range("E157").[B]Resize([COLOR=#ff0000]0[/COLOR], 4).Valu[/B]e = "=SUM(R158C)"
MsgBox .Range("E157").Resize(0, 4).Address
End With
End Sub
em cảm ơn!
Resize(Số dòng, Số cột) ---> Vậy làm quái gì có cái chuyện Số dòng (hoặc số cột) = 0 hả Diễm?
 
Upvote 0
Cho em hỏi, Em giả sử vòng lặp For i=3 to 10 ( Nghĩa là i liên tục từ 3 đến 10) ...... Next


Còn trường hợp của em là i từ 3 đến 6 (bỏ 7) và từ 8 đến 10. Như vậy em có dùng For Next được không?
Em cảm ơn.
 
Chỉnh sửa lần cuối bởi điều hành viên:
Upvote 0
Cho em hỏi, Em giả sử vòng lặp For i=3 to 10 ( Nghĩa là i liên tục từ 3 đến 10) ...... Next


Còn trường hợp của em là i từ 3 đến 6 (bỏ 7) và từ 8 đến 10. Như vậy em có dùng For Next được không?
Em cảm ơn.

Đương nhiên là được và muốn nhảy qua giá trị nào của i thì bạn thêm If vào ngay dưới câu lệnh For

Ví dụ nhảy qua 7 thì câu lệnh là: if i = 7 then i = 8
 
Upvote 0
Cho em hỏi, Em giả sử vòng lặp For i=3 to 10 ( Nghĩa là i liên tục từ 3 đến 10) ...... Next
Còn trường hợp của em là i từ 3 đến 6 (bỏ 7) và từ 8 đến 10. Như vậy em có dùng For Next được không?
Em cảm ơn.

nếu các trường hợp loại trừ ít (trong trường hợp này chỉ loại trừ 7)

PHP:
For i = 3 to 10
If i = 7 then i = 8
...
Next
 
Upvote 0
Đương nhiên là được và muốn nhảy qua giá trị nào của i thì bạn thêm If vào ngay dưới câu lệnh For

Ví dụ nhảy qua 7 thì câu lệnh là: if i = 7 then i = 8

Anh cho em ví dụ cụ thể được khộng! em cảm ơn.
Thôi đã có bài của thầy ptm0412, Thầy ptm0412 nói nếu loại trừ ít, như vậy nếu loại trừ nhiều thì giải quyết như thế nào ạ!
 
Lần chỉnh sửa cuối:
Upvote 0
Hồi trước có học lập trình cơ bản (Turbo Pascal 3.0) thầy dặn không nên thay đổi giá trị của biến điều khiển trong vòng lặp For To/Downto Do, vì thói quen này có thể dẫn đến các trường hợp bất thường.
Tôi vẫn quen dùng cách "cổ điển" khi phải nhảy băng qua các giá trị:
If i<>7 then (hoặc một điều kiện nào đó về i chẳng hạn)
... xử lý
End If
mặc dầu nó chậm hơn nhưng câu lệnh rõ ràng hơn.
 
Upvote 0
Anh cho em ví dụ cụ thể được khộng! em cảm ơn.
Thôi đã có bài của thầy ptm0412, Thầy ptm0412 nói nếu loại trừ ít, như vậy nếu loại trừ nhiều thì giải quyết như thế nào ạ!

Loại trừ hơi nhiều thì làm như hoangvuluan:

PHP:
For i = 3 to 10
If i <> 5 Or i <> 7 Or i <> 8 Then
..
End If
Next

Loại trừ nhiều hơn tí nữa thì dùng If với phủ định

Loại trừ nhiều hơn nữa, thì bỏ vòng For mà dùng If đơn thuần.
 
Upvote 0
Anh cho em ví dụ cụ thể được khộng! em cảm ơn.
Thôi đã có bài của thầy ptm0412, Thầy ptm0412 nói nếu loại trừ ít, như vậy nếu loại trừ nhiều thì giải quyết như thế nào ạ!
Nhiều là nhiều cở bao nhiêu? Bạn thử cho ví dụ xem
Nếu nhiều quá, ta có thể cho mấy thằng loại trừ ấy vào Dictionary, xong dùng phương thức Dic.Exists để xem biến chạy i có tồn tại trong Dic hay không... đại khái thế
 
Upvote 0
Nếu nhiều quá, ta có thể cho mấy thằng loại trừ ấy vào Dictionary, xong dùng phương thức Dic.Exists để xem biến chạy i có tồn tại trong Dic hay không... đại khái thế

Hì hì em thấy Dictionary và phương thức Dic.Exists còn cao quá đối với em.
Không biết có bài nào đơn giản & dễ hiểu về Dictionary thì thầy chỉ giùm, em có thấy các bài trên mạng nhưng còn khó hiểu quá! em cảm ơn.
 
Upvote 0
Hì hì em thấy Dictionary và phương thức Dic.Exists còn cao quá đối với em.
Không biết có bài nào đơn giản & dễ hiểu về Dictionary thì thầy chỉ giùm, em có thấy các bài trên mạng nhưng còn khó hiểu quá! em cảm ơn.
"Không có việc gì khó, chỉ sợ lòng không bền"
Chẳng nhẽ bạn thấy khó rồi xin rút lui sao? phải lao vào mới tiến bộ được chứ
MÌnh nói với bạn Dictionary rất hay và không khó hiểu lắm đâu (mình cũng mới học đây thôi) các anh chị sẵn sàng giúp bạn, khó đến đâu cứ hỏi
Tham khảo Link: http://www.giaiphapexcel.com/forum/showthread.php?60643-Tổng-quan-về-Dictionary
 
Lần chỉnh sửa cuối:
Upvote 0
Hì hì em thấy Dictionary và phương thức Dic.Exists còn cao quá đối với em.
Không biết có bài nào đơn giản & dễ hiểu về Dictionary thì thầy chỉ giùm, em có thấy các bài trên mạng nhưng còn khó hiểu quá! em cảm ơn.

Bạn có thể tập một ví dụ đơn giản về Dictionary là bạn lấy 1 bảng dữ liệu gồm nhiều cái tên ra, xong bạn dùng Dic để lọc thành những tên duy nhất. Như vậy bạn chỉ cần thực hiện các thao tác là
1/ Duyệt bảng, lấy từng phần tử đem ra coi trong Dic đã tồn tại chưa, bằng phương thức Exists
2/ Nếu tồn tại thì không làm gì, nếu không tồn tại thì cho vào Dic bằng phương thức Add
3/ Xuất Dic ra bằng cách xuất mảng Keys của nó.

Mình nghĩ ba bước cơ bản như vậy cũng rất dễ làm bạn à, bạn thử xem.
 
Upvote 0
Bạn có thể tập một ví dụ đơn giản về Dictionary là bạn lấy 1 bảng dữ liệu gồm nhiều cái tên ra, xong bạn dùng Dic để lọc thành những tên duy nhất. Như vậy bạn chỉ cần thực hiện các thao tác là
1/ Duyệt bảng, lấy từng phần tử đem ra coi trong Dic đã tồn tại chưa, bằng phương thức Exists
2/ Nếu tồn tại thì không làm gì, nếu không tồn tại thì cho vào Dic bằng phương thức Add
3/ Xuất Dic ra bằng cách xuất mảng Keys của nó.

Mình nghĩ ba bước cơ bản như vậy cũng rất dễ làm bạn à, bạn thử xem.




Hì hì có thể thành viên của mình đã up level rồi nên hết căn bản nhất rồi!
 
Upvote 0
Hồi trước có học lập trình cơ bản (Turbo Pascal 3.0) thầy dặn không nên thay đổi giá trị của biến điều khiển trong vòng lặp For To/Downto Do, vì thói quen này có thể dẫn đến các trường hợp bất thường.
Tôi vẫn quen dùng cách "cổ điển" khi phải nhảy băng qua các giá trị:
If i<>7 then (hoặc một điều kiện nào đó về i chẳng hạn)
... xử lý
End If
mặc dầu nó chậm hơn nhưng câu lệnh rõ ràng hơn.

Tôi cũng nghĩ là việc thay đổi i trong vòng lặp là thói quen lập trình xấu. Một vòng lặp dài mà có vài chỗ như thế thì code sẽ rất tối. Mà ai thừa hưởng nhưng code đó thì thì khổ lắm. Ông viết nhưng ông thôi việc rồii còn tôi ở lại tôi khổ mặc tôi?
Tôi không nhớ trong Turbo Pascal như thế nào nhưng trong Delphi (Object Pascal) thì không được phép thay đổi i trong vòng lặp. Nếu có thì code sẽ không compile được.
Vd. trong Delphi để nhẩy qua giá trị thì dễ thôi.
if i = 7 then continue; ' <-- vòng lặp tiếp theo
Hoặc viết như bạn.
Chắc trong Turbo Pascal cũng thế thôi.
 
Upvote 0
Cho em hỏi, Em giả sử vòng lặp For i=3 to 10 ( Nghĩa là i liên tục từ 3 đến 10) ...... Next


Còn trường hợp của em là i từ 3 đến 6 (bỏ 7) và từ 8 đến 10. Như vậy em có dùng For Next được không?
Em cảm ơn.

Tôi thường làm như vầy:

PHP:
Private Sub NhaySo()
    ''Nhay 1 so:
    For i = 3 To 10
        If i = 7 Then GoTo NextI
        Debug.Print i
NextI:
    Next
End Sub



Private Sub NhaySo1()
    ''Lay so le:
    For i = 1 To 10 Step 2
        Debug.Print i
    Next
End Sub



Private Sub NhaySo2()
    ''Lay so chan:
    For i = 2 To 10 Step 2
        Debug.Print i
    Next
End Sub



Private Sub NhaySo3()
    ''Lay 1, 2, 5, 6, 8 , 9, 10:
    For i = 1 To 10
        Select Case i
            Case 1, 2, 5, 6, 8 To 10: Debug.Print i
        End Select
    Next
End Sub

Bấm Ctrl+G để xem kết quả trong Immediate.
 
Lần chỉnh sửa cuối:
Upvote 0
Giúp em viết code: xóa phần nằm sau dấu "=" trong chuỗi
Ví dụ:
Móng: (1+2)*2 = 1
Chuyển thành:
Móng: (1+2)*2
 
Upvote 0
Giúp em viết code xoá giá trị sau dấu '="

Em gửi file bác xem giúp(sửa phần giá trị trong cột E)
Thank bác nhiều
 

File đính kèm

Upvote 0
Em gửi file bác xem giúp(sửa phần giá trị trong cột E)
Thank bác nhiều

Bạn insert một cột phụ tại ô ở hàng 7 của cột phụ bạn đặt công thức:

=IF(ISERROR(LEFT(E7,FIND(" =",E7))),E7,LEFT(E7,FIND(" =",E7)))


Sau đó bạn chỉ việc copy giá trị của cột này rồi paste value qua cột Phần Móng.
 
Upvote 0
Hàm trên em thấy đang báo lỗi, mà nếu paste value thì sẽ mất giá trị trong các ô có tên đầu công việc (phần chỉ chứa text).
Bảng biểu khá nhiều và phải lặp lại công việc nên em muốn tạo macro cho thuận tiện (do mù mờ về code nên khó quá). Em gửi lên bác xem giúp em chèn thêm đoạn code xóa giá trị trên:
Sub TLDG()Dim i
For i = 8 To 4000
If (Cells(i, "E")) <> "" Then
If (Cells(i, "D")) = "" Then
Cells(i, "E").Select
' Doan code can them de xoa gia tri sau dau "=" trong Cell da duoc chon
Application.Run Range("Trasolieu")
End If
End If
Next i
End Sub
Đoạn code em cần có tác dụng:
Giá trị của ô được chọn (hàng i, cột E)= Giá trị của phần nằm trước dấu "=" trong chuỗi của ô được chọn (nếu có dấu "="
Hoặc nâng cao hơn, giúp e tạo macro:
Nếu đánh chuỗi giá trị có dấu '=" vào 1 ô được chọn (hàng i,cột E) thì tự đông xóa phần sau dấu "=" ngay khi nhập dữ liệu. Ví dụ:Khi đánh vào ô (hàng i, cột E)
Móng: 1+2 = 4
tự động chuyển thành:
Móng: 1+2 (xóa phần sau dấu "="
 
Lần chỉnh sửa cuối:
Upvote 0
Code này coi thế nào

Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Column = 5 Then
Target.Replace "=*", ""
End If
End Sub
 
Upvote 0
Code này coi thế nào

Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Column = 5 Then
Target.Replace "=*", ""
End If
End Sub
Cái này nếu để riêng thành 1 module, em bấm F5 sao lại ra bảng chọn macro (như thao tác bấm Alt+F8). Còn nếu để trong code chung thì nó báo lỗi
Sub TLDG()
Dim i
For i = 8 To 4000
If (Cells(i, "E")) <> "" Then
If (Cells(i, "D")) = "" Then
Cells(i, "E").Select
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Column = 5 Then
Target.Replace "=*", ""
End If
End Sub
Application.Run Range("Trasolieu")
End If
End If
Next i
End Sub
 
Upvote 0
Code này coi thế nào

Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Column = 5 Then
Target.Replace "=*", ""
End If
End Sub
Code của bac Quanghai giải quyết yêu cầu: nhập có dấu "=" thì bỏ phía sau
Còn nếu bạn muốn bỏ phần sau dấu "=" nếu cột D tương ứng rỗng thì có thể dùng cái này
PHP:
Sub GPE()
      For i = 6 To Cells(65536, 5).End(xlUp).Row    
         If Cells(i, 4) = "" Then Cells(i, 5).Replace "=*", ""
      Next
End Sub
 
Upvote 0
Cái này nếu để riêng thành 1 module, em bấm F5 sao lại ra bảng chọn macro (như thao tác bấm Alt+F8). Còn nếu để trong code chung thì nó báo lỗi

Nếu muốn viết thành 1 sub thì như thế này sẽ nhanh hơn cho dữ liệu nhiều
Nếu xử lý trên sheet thì chậm lắm

PHP:
Sub xoa_chuoi()
Dim i, kq()
kq = Range([E8], [E65536].End(3)).Offset(, -1).Resize(, 2).Value
With CreateObject("vbscript.regexp")
   .Global = True
   .Pattern = "=.*"
   For i = 1 To UBound(kq)
      If kq(i, 1) = "" Then
         If kq(i, 2) <> "" Then
            kq(i, 2) = .Replace(kq(i, 2), "")
         End If
      End If
   Next
End With
[D8].Resize(i - 1, 2) = kq
End Sub
 
Upvote 0
Nếu muốn viết thành 1 sub thì như thế này sẽ nhanh hơn cho dữ liệu nhiều
Nếu xử lý trên sheet thì chậm lắm

PHP:
Sub xoa_chuoi()
Dim i, kq()
kq = Range([E8], [E65536].End(3)).Offset(, -1).Resize(, 2).Value
With CreateObject("vbscript.regexp")
   .Global = True
   .Pattern = "=.*"
   For i = 1 To UBound(kq)
      If kq(i, 1) = "" Then
         If kq(i, 2) <> "" Then
            kq(i, 2) = .Replace(kq(i, 2), "")
         End If
      End If
   Next
End With
[D8].Resize(i - 1, 2) = kq
End Sub
Code của bác Quanghai có tốc độ giải quyết bài toán trên nhanh hơn nhiều so với code của bác dhn46.
Nhờ bác giải quyết triệt để bài toán này giúp e
Tạo ra 1 maco là tốt nhất (ưu tiến tốc độ vì bảng dữ liệu nhiều), gồm 2 tác dụng:
1. xoá phần giá trị nằm sau dấu "="
2. Trong giá trị có nhiều đoạn có nhiều "dấu cách", giúp e chuyển thành chỉ còn 1 dấu cách tại các vị trí tương ứng.
ví dụ:
Móng: 1+2 = 3 = 4 ('ban đầu, sau dấu ":" nhiều dấu cách, sau số "2" nhiều dấu cách ) (tác giả có thể hạn chế số dấu cách từ 1-9 hoặc 1-4 để ưu tiên tốc độ xử lý)
sau khi chuyển:
Móng: 1+2 ('sau dấu ":" chỉ còn 1 dấu cách, sau số 2 chỉ còn 1 dấu cách)
 
Lần chỉnh sửa cuối:
Upvote 0
Code của bác Quanghai có tốc độ giải quyết bài toán trên nhanh hơn nhiều so với code của bác dhn46.
Nhờ bác giải quyết triệt để bài toán này giúp e
Tạo ra 1 maco là tốt nhất (ưu tiến tốc độ vì bảng dữ liệu nhiều), gồm 2 tác dụng:
1. xoá phần giá trị nằm sau dấu "="
2. Trong giá trị có nhiều đoạn có nhiều "dấu cách", giúp e chuyển thành chỉ còn 1 dấu cách tại các vị trí tương ứng.
ví dụ:
Móng: 1+2 = 3 = 4 ('ban đầu, sau dấu ":" nhiều dấu cách, sau số "2" nhiều dấu cách ) (tác giả có thể hạn chế số dấu cách từ 1-9 hoặc 1-4 để ưu tiên tốc độ xử lý)
sau khi chuyển:
Móng: 1+2 ('sau dấu ":" chỉ còn 1 dấu cách, sau số 2 chỉ còn 1 dấu cách)

Chắc sợ up file lên rồi nghẽn mạng hay sao ấy.
PHP:
Sub xoa_chuoi()
Dim i, kq()
kq = Range([E8], [E65536].End(3)).Offset(, -1).Resize(, 2).Value
With CreateObject("vbscript.regexp")
   .Global = True
   .Pattern = "=.*"
   For i = 1 To UBound(kq)
      If kq(i, 1) = "" Then
         If kq(i, 2) <> "" Then
            kq(i, 2) = Trim(.Replace(kq(i, 2), "")) & " "
         End If
      End If
   Next
End With
[D8].Resize(i - 1, 2) = kq
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Xin viết code trong dự toán

Bác chỉnh giùm em để chuyển dạng dữ liệu tương tự ô E8 thành dạng dữ liệu giống ô E9
 
Upvote 0

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

Back
Top Bottom