Hỏi đáp về VBA (các vấn đề căn bản nhất)

Liên hệ QC

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

  • baitap1.xls
    28 KB · Đọc: 244
Lần chỉnh sửa cuối:
PHP:
Option Explicit
Sub GPE()
 Dim Cls As Range
 Dim HL As String
 
 For Each Cls In Range([C4], [C4].End(xlDown))
    HL = Left(Cls.Value, 2)
    If HL = "Gi" Then
        Cls.Offset(0, 1).Value = 5
    ElseIf HL = "Kh" Then
        Cls.Offset(0, 1).Value = 4
    ElseIf HL = "TB" Then
        Cls.Offset(0, 1).Value = 3
    ElseIf HL = "Ké" Then
        Cls.Offset(0, 1).Value = 1
    Else
        Cls.Offset(0, 1).Value = 2
    End If
 Next Cls
End Sub
 
Upvote 0
Nhờ sửa giúp đoạn code sau.

Với code trên em chỉ có thể chạy được trên sheet Tong hop N-X. Nếu chuyển qua sheet khác chạy code trên thì báo lỗi dòng With sheet3.range([f8], [F56636].End(xlUp)). Anh chị có thể sửa lại giúp em với.
With Sheet3.Range([f8], [F56636].End(xlUp))
.Offset(1, 0).Value = "=SUMIF('Nhap - Xuat'!$E$7:$E$1020,'Tong hop N-X'!B9,'Nhap - Xuat'!$H$7:$H$1020)"
.Offset(1, 1).Value = "=SUMIF('Nhap - Xuat'!$E$7:$E$1020,'Tong hop N-X'!B9,'Nhap - Xuat'!$j$7:$j$1020)"
.Offset(1, 2).Value = "=SUMIF('Nhap - Xuat'!$E$7:$E$1020,'Tong hop N-X'!B9,'Nhap - Xuat'!$i$7:$i$1020)"
.Offset(1, 3).Value = "=SUMIF('Nhap - Xuat'!$E$7:$E$1020,'Tong hop N-X'!B9,'Nhap - Xuat'!$k$7:$k$1020)"
.Offset(1, 4).Value = "=(d9+F9-H9)"
.Offset(1, 5).Value = "=(e9+g9-i9)"
With .Resize(, 6)
.Value = .Value
On Error Resume Next
End With
End With
 
Upvote 0
Không nói rõ nội dung thông báo lỗi như thế nào nhưng Dòng này : With Sheet3.Range([f8], [F56636].End(xlUp))

bạn thêm thành : With Sheet3.Range(sheet3.[f8], sheet3.[F56636].End(xlUp))

Xem có bị lỗi nữa không nhé - không biết tôi có hiểu nhầm ý bạn không (đứng ở sheet khác chạy code cho sheet3)

Mình đọc lại chỗ này :Nếu chuyển qua sheet khác nghĩa là ta phải thay thằng sheet3 thành thằng sheet khác chính là sheet mà mình muốn chạy code rồi, thế thì bạn phải xem sheet bạn đang chạy code là sheet nào để thay cho chuẩn nhé vì không có file đính kèm nên không biết chỉ cho bạn thay bằng sheet nào, hix
 
Lần chỉnh sửa cuối:
Upvote 0
Cảm ơn mình làm được rồi. Đúng là đổi thành :With Sheet3.Range(sheet3.[f8], sheet3.[F56636].End(xlUp)) mới chạy.
 
Upvote 0
Bạn nên viết như thế này dễ nhìn hơn:

With Sheet3.Range("F8:F" & Sheet3.[F65536].End(3).Row)
 
Upvote 0
Anh cho em hỏi End(3) = End(xlup) hả anh?

Người ta thường viết tắt theo vị trí của phương thức này:

xlToLeft = 1

xlToRight = 2

xlUp = 3

xlDown = 4

Nhưng nếu đúng trong list contants thì nó phải như sau:

xlToLeft = -4159

xlToRight = -4161

xlUp = -4162

xlDown = -4121

Nhưng cá nhân tôi thì thích viết kiểu chuỗi, nó thể hiện một cách tường minh, nhìn vào khỏi cần thắc mắc nó là gì.
 
Upvote 0
Người ta thường viết tắt theo vị trí của phương thức này:

xlToLeft = 1

xlToRight = 2

xlUp = 3

xlDown = 4

Nhưng nếu đúng trong list contants thì nó phải như sau:

xlToLeft = -4159

xlToRight = -4161

xlUp = -4162

xlDown = -4121

Nhưng cá nhân tôi thì thích viết kiểu chuỗi, nó thể hiện một cách tường minh, nhìn vào khỏi cần thắc mắc nó là gì.

Không chỉ là vấn đề chuyên nghiệp mà đúng là phải tường minh. Mình viết sao cho người khác đọc cũng hiểu.
Mà bạn hãy tưởng tượng một code dùng toàn số xem sao. Rồi ai viết trong API cũng thay mọi thông điệp bằng số hết thì chắc là ngày hôm nay bạn tìm kiếm trên google vất vả lắm. Muốn tìm những ví dụ hướng dẫn dùng thông điệp WM_HICHIC thì không tìm thấy vì những tác giả đã viết 2 (3, 5, 1000) thay cho WM_HICHIC rồi. Mà gõ vào google số 2 để tìm? Có mà điên.

Ngay cả khi tự tạo cho mình một thông điệp riêng cũng chả ai lấy nó là xyz cả. Mà phải là

Private/Public "một cái tên gợi ý rất nhiều" = xyz

Dùng toàn số là a ma tơ, là thói quen xấu. Cứ hỏi bất cứ ai có kinh nghiệm lập trình thì người ta cũng sẽ nói như thế. Chấm hết.
 
Upvote 0
Làm thế nào để VBA chỉ có tác dụng cho file chứa code?

Em xin hỏi:
- Tại sao file chứa code VBA của em khi mở lên lại có tác dụng cho cả các file khác?
+ Trong Workbook em viết:
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
Call Callsub
End Sub
+ Trong Module em viết:
Sub Callsub()
Application.OnKey "{ENTER}", "FindPic"
End Sub

Khi em mở các file khác thì đều thực thi code này.
Xin các anh chỉ giáo!
 
Upvote 0
Em xin hỏi:
- Tại sao file chứa code VBA của em khi mở lên lại có tác dụng cho cả các file khác?
+ Trong Workbook em viết:
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
Call Callsub
End Sub
+ Trong Module em viết:
Sub Callsub()
Application.OnKey "{ENTER}", "FindPic"
End Sub

Khi em mở các file khác thì đều thực thi code này.
Xin các anh chỉ giáo!

OnKey là phương thức của object Application mà. Vậy nhấn Enter trong "toàn bộ lãnh thổ" sẽ gây ra việc thực thi FindPic.
Nếu bạn chỉ muốn thực thi FindPic khi nhấn Enter trong tỉnh xyz thôi thì ...


Bạn làm thế này

ThisWorkbook
Mã:
Private Sub Workbook_Activate()
    Callsub True
End Sub

Private Sub Workbook_Deactivate()
    Callsub False
End Sub

module
Mã:
Sub Callsub(ByVal DoSet As Boolean)
    If DoSet Then
        Application.OnKey "{ENTER}", "FindPic"
    Else
        Application.OnKey "{ENTER}", ""
    End If
End Sub

Hoặc

Mã:
Private Sub Workbook_Activate()
    Application.OnKey "{ENTER}", "FindPic"
End Sub

Private Sub Workbook_Deactivate()
    Application.OnKey "{ENTER}", ""
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Cảm ơn anh @siwtom tôi đã thực hiện được!
 
Upvote 0
Cảm ơn anh Nghĩa nhiều lắm ạ! Tại em thấy có 1 số code vẫn dùng if......Endif nên gặp IIF em không hiểu là gì?
Anh Nghĩa và anh Ba Tê có thể suy nghĩ giúp đỡ em 3 hàm còn lại trong File đính kèm ở bài #233 được không ạ. Nếu có thêm chú thích cho em thì càng tốt. Em mới tìm hiểu về VBA nên còn nhiều điều bỡ ngỡ lắm ạ!
P/S: Nhân tiện cho em hỏi ý nghĩa UBound trong lệnh For I = 1 To UBound(Arr, 1) với ạ.

Những cái khác bạn từ từ nghiên cứu, học lập trình thì chớ vội vàng chi! Nhưng với dòng màu đỏ, Ubound là hàm để tính cận trên của một mảng (array).

Cận trên (Ubound), cận dưới (Lbound) là gì? Tạm thời bạn xem ở bài này nhé:

http://www.giaiphapexcel.com/forum/showthread.php?22361-Lbound-và-UBound-là-gì&p=155471#post155471
 
Upvote 0
Những cái khác bạn từ từ nghiên cứu, học lập trình thì chớ vội vàng chi! Nhưng với dòng màu đỏ, Ubound là hàm để tính cận trên của một mảng (array).

Cận trên (Ubound), cận dưới (Lbound) là gì? Tạm thời bạn xem ở bài này nhé:

http://www.giaiphapexcel.com/forum/showthread.php?22361-Lbound-và-UBound-là-gì&p=155471#post155471
Em cảm ơn anh nhiều ạ! Anh Nghĩa cho em hỏi ngoài hàm Ubound có thể thay bằng hàm nào khác không ạ?
 
Lần chỉnh sửa cuối:
Upvote 0
Tôi viết lại theo kiểu tôi làm:
PHP:
Public Function GetMon(Ngay As Date, Thu As Long, Tiet As Long, Rng As Range) As Variant
Dim Arr(), Cll As Range, I As Long, J As Long, Col As Long
With Sheets("tkb")
    Arr = Rng.Value
    For I = 1 To UBound(Arr, 1)
        If Arr(I, 1) = Ngay Then
            Col = ((Thu - 1) * 10 - 9) + (Tiet * 2 - 1)
            GetMon = IIf(Arr(I, Col) = "", "", Arr(I, Col))
            Exit For
        End If
    Next I
End With
End Function
Ví dụ ô C6 thì công thức là:
=GetMon($A$8;$A$7;$B6;Tkb!$B$4:$BJ$41)

Anh Ba Tê có thể giúp em viết tiếp 3 hàm còn lại không ạ?
 
Lần chỉnh sửa cuối:
Upvote 0
Ubound là hàm để tính cận trên của một mảng (array).

Cận trên (Ubound), cận dưới (Lbound) là gì? Tạm thời bạn xem ở bài này nhé:

http://www.giaiphapexcel.com/forum/showthread.php?22361-Lbound-và-UBound-là-gì&p=155471#post155471

Không phải cận trên và cận dưới, mà là chỉ số trên và chỉ số dưới. Trong toán học và lập trình phải phát biểu cho chính xác.

Cận trên của 1 số A trong 1 mảng giá trị là số nhỏ nhất của mảng, và lớn hơn A
Cận dưới của số A trong 1 mảng giá trị là số lớn nhất của mảng, và nhỏ hơn A

Với Base 0 thì LBound = 0, UBound = số phần tử của chiều đang đếm - 1
Với Base 1 và mảng lấy giá trị trực tiếp từ range trên sheet thì LBound = 1, UBound = số phần tử của chiều đang đếm

Nói chiều đang đếm vì mảng có thể có 1 hoặc nhiều chiều. LBound và UBound phải nói rõ tính theo chiều nào, không ghi thì hiểu là chiều thứ nhất.
 
Upvote 0
Không phải cận trên và cận dưới, mà là chỉ số trên và chỉ số dưới. Trong toán học và lập trình phải phát biểu cho chính xác.

Cận trên của 1 số A trong 1 mảng giá trị là số nhỏ nhất của mảng, và lớn hơn A
Cận dưới của số A trong 1 mảng giá trị là số lớn nhất của mảng, và nhỏ hơn A

Với Base 0 thì LBound = 0, UBound = số phần tử của chiều đang đếm - 1
Với Base 1 và mảng lấy giá trị trực tiếp từ range trên sheet thì LBound = 1, UBound = số phần tử của chiều đang đếm

Nói chiều đang đếm vì mảng có thể có 1 hoặc nhiều chiều. LBound và UBound phải nói rõ tính theo chiều nào, không ghi thì hiểu là chiều thứ nhất.
Thầy Mĩ có thể nghiên cứu giúp em các code trong File đính kèm ở #233 và giải thích giúp em được không ạ.
 
Upvote 0
Web KT
Back
Top Bottom