Thông tin
  • Đánh dấu xác nhận câu hỏi đã được giải quyết để giúp diễn đàn nâng cao chất lượng [cách sử dụng]
  • Vui lòng đọc nội qui diễn đàn để tránh bị xóa bài viết [nội qui]
  • Tìm kiếm trước khi đặt câu hỏi

đổi từ sự kiện selectionchange thành public sub (macro)  Chủ đề đã được giải quyết

Nơi trao đổi về VBA (Visual Basic for Application), lập trình cho ứng dụng Microsoft Office, AutoCAD...

Điều hành viên: tungblt

đổi từ sự kiện selectionchange thành public sub (macro)

Gửi bàigửi bởi tuanbonus » Thứ 5 19/07/2012 8:59 pm

dears các anh chị & anh TruongPhu.

giúp em từ 1 sự kiện (worksheet_selectionchange) biến thành 1 public sub đại khái như 1 macro để dùng chung nếu định dạng giống nhau. dưới đây là đoạn code để làm được như thế thì mình sẽ khai lại các biến như thế nào or là có hướng nào không? giúp em cái này với!

Mã: Chọn tất cả
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim Vung, I, J, kK, Mg, TachDm, TachMau, Tong, K, A, B
    If Not Intersect(Target, Range([K132], [K10000].End(xlUp))) Is Nothing Or Not Intersect(Target, Range([AI132], [AI10000].End(xlUp))) Is Nothing Then
   If ActiveCell.Interior.ColorIndex = 6 Then
    UserForm1.Show
    Else
    Vung = ActiveCell.Offset(, -3).Resize(, 14)
        Tong = Tong + Len(ActiveCell) - Len(Replace(ActiveCell, "+", "")) + 1
        ReDim Mg(1 To Tong, 1 To 7)
                TachDm = Split(ActiveCell, "+")
                TachMau = Split(Vung(1, 1), "/")
                For J = LBound(TachDm) To UBound(TachDm)
                    K = K + 1
                On Error GoTo Lôi
                      Mg(K, 1) = TachDm(J): Mg(K, 2) = TachMau(J): Mg(K, 3) = Vung(1, 12): Mg(K, 4) = Vung(1, 11): Mg(K, 5) = IIf(Mg(K, 3) = "M", 1 / Vung(1, 14), Vung(1, 14)): Mg(K, 6) = Range("AJ108"): Mg(K, 7) = Range("P112")
                     
                    Next J
    ActiveCell.Interior.ColorIndex = 6
 Dim Ws As Worksheet
    Set Ws = Application.Workbooks("TH_chitiet.xls").Worksheets("TH_chitiet")
    With Ws.[B1000].End(xlUp)(2)
        If .Row = 7 Then
            .Offset(, -1) = 1
        Else
            .Offset(, -1) = 1 + Application.WorksheetFunction.Max(Ws.Range((Ws.[B5]), (Ws.[B10000].End(xlUp))).Offset(, -1))
        End If
    End With
    Ws.[B1000].End(xlUp)(2).Resize(K, 7) = Mg
    Application.Workbooks("TH_chitiet").Save
    Ws.Select
   
    End If
    End If
   
    Set Ws = Nothing
Exit Sub
Lôi:  If (Mg(K, 2) = Empty) Or (Mg(K, 3) = Empty) Or (Mg(K, 4) = Empty) Or (Mg(K, 5) = Empty) Then
         UserForm2.Show
      End If
End Sub


em cảm ơn nhiều!
tuanbonus
Thành viên chính thức
Thành viên chính thức
 
Bài viết: 14
Ngày tham gia: Thứ 4 20/06/2012 2:03 pm
Đã cảm ơn: 8 lần
Được cảm ơn: 0 lần

Re: đổi từ sự kiện selectionchange thành public sub (macro)

Gửi bàigửi bởi truongphu » Thứ 6 20/07/2012 12:15 pm

tuanbonus đã viết:sự kiện (worksheet_selectionchange) biến thành 1 public sub đại khái như 1 macro

Cấu trúc một Sub hay Function giống nhau. Sub cũng gọi là Macro (gọi trong office)

Function AAA(xxx) AS yyy
AAA là tên, xxx là các đối số cần thiết, AS yyy là giá trị trả về. Sub không có giá trị trả về, nó chỉ thực hiện các công việc theo lệnh. vd:
Sub BBB()
ở trên, Sub BBB không có đối số (thường macro không đối số). Đương nhiên Sub cũng có thể có đối số.

Với:
Mã: Chọn tất cả
Sub Worksheet_SelectionChange(ByVal Target As Range)

có đối số là Target.
Chuyển qua macro ZZZ không đối số:
Sub ZZZ()
Vì Target là Selection, nên bạn phải đưa Selection vào Sub ZZZ
Mã: Chọn tất cả
dim ppp As Range
set ppp = Selection
If Not Intersect(ppp...

các lệnh khác giữ nguyên

Chuyển qua macro EEE có đối số:
vd muốn thay màu
Mã: Chọn tất cả
Sub EEE(ByVal Màu As Integer)
'...
If ActiveCell.Interior.ColorIndex = Màu Then
'...

Khi gọi sub này, ta viết:
Mã: Chọn tất cả
EEE 5

(5=blue)

vd thay đối số thứ hai của hàm Intersect
Mã: Chọn tất cả
Sub EEE(ByVal Màu As Integer, RangeThu2 As Range)
dim ppp As Range
set ppp = Selection
If Not Intersect(ppp, RangeThu2, ...

các lệnh khác giữ nguyên

Khi gọi sub này, ta viết:
Mã: Chọn tất cả
dim myrange as range
set myrange = Range("H12")
EEE 8, myrange

(8=cyan)
Các biến trong câu:
Dim Vung, I, J, kK, Mg, TachDm, TachMau, Tong, K, A, B
Không đưa vào đối số, vì đấy chỉ phục vụ cho việc tính toán.

Chỉ còn lại đối số thứ 3... của hàm Intersect có thể đưa vào đối số.
Cách làm như trên
o0o--truongphu--o0o

.........
Ghé thăm:
Chuyện Linh Tinh
Hình đại diện của thành viên
truongphu
VIP
VIP
 
Bài viết: 4721
Ngày tham gia: Chủ nhật 04/11/2007 10:57 am
Đến từ: Cam Đức, Khánh hòa
Đã cảm ơn: 13 lần
Được cảm ơn: 470 lần

Re: đổi từ sự kiện selectionchange thành public sub (macro)

Gửi bàigửi bởi tuanbonus » Thứ 6 20/07/2012 11:24 pm

dear anh TruongPhu,
em biết đây là sự kiện selectionchange click vào bất cứ cell nào của cột đã mặt định, thì sẽ tách nhóm dữ liệu của cell đó kèm theo 4 cells kế tiếp qua 1 file khác có tính toán.

em muốn tạo nó thành 1 macro có thể add nó vào trong add-ins khi cần gọi ra để thực hiện

em đọc và vọc mãi theo hướng dẫn của anh suốt từ chiều mà không ra, anh có thể giúp em chỉnh lại code em đính kèm được không anh? và cho em biết cách gọi nó ra cụ thể như thế nào? cám ơn anh nhiều.
Bạn không được cấp phép để xem tập tin đính kèm trong bài viết này.
tuanbonus
Thành viên chính thức
Thành viên chính thức
 
Bài viết: 14
Ngày tham gia: Thứ 4 20/06/2012 2:03 pm
Đã cảm ơn: 8 lần
Được cảm ơn: 0 lần

Re: đổi từ sự kiện selectionchange thành public sub (macro)

Gửi bàigửi bởi tuanbonus » Chủ nhật 22/07/2012 10:56 pm

giúp em tí xíu nữa đi anh TruongPhu! cám ơn nhiều
tuanbonus
Thành viên chính thức
Thành viên chính thức
 
Bài viết: 14
Ngày tham gia: Thứ 4 20/06/2012 2:03 pm
Đã cảm ơn: 8 lần
Được cảm ơn: 0 lần

Re: đổi từ sự kiện selectionchange thành public sub (macro)

Gửi bàigửi bởi truongphu » Thứ 2 23/07/2012 9:01 pm

Code của bạn (bài đầu) dùng rất khá..
Vậy cớ sao hướng dẫn như thế bạn còn bí?
=====
1- Muốn làm một macro, vd AAA bạn viết:
Mã: Chọn tất cả
Private Sub AAA()
End Sub

2 - Bạn copy toàn bộ nội dung trong Worksheet_SelectionChange và dán vào:
Mã: Chọn tất cả
Private Sub AAA()
Dim Vung, I, J, kK, Mg, TachDm, TachMau, Tong, K, A, B
    If Not Intersect(Target, Range([K132], [K10000].End(xlUp))) Is Nothing Or Not Intersect(Target, Range([AI132], [AI10000].End(xlUp))) Is Nothing Then
   If ActiveCell.Interior.ColorIndex = 6 Then
    UserForm1.Show
    Else
    Vung = ActiveCell.Offset(, -3).Resize(, 14)
        Tong = Tong + Len(ActiveCell) - Len(Replace(ActiveCell, "+", "")) + 1
        ReDim Mg(1 To Tong, 1 To 7)
                TachDm = Split(ActiveCell, "+")
                TachMau = Split(Vung(1, 1), "/")
                For J = LBound(TachDm) To UBound(TachDm)
                    K = K + 1
                On Error GoTo Lôi
                      Mg(K, 1) = TachDm(J): Mg(K, 2) = TachMau(J): Mg(K, 3) = Vung(1, 12): Mg(K, 4) = Vung(1, 11): Mg(K, 5) = IIf(Mg(K, 3) = "M", 1 / Vung(1, 14), Vung(1, 14)): Mg(K, 6) = Range("AJ108"): Mg(K, 7) = Range("P112")
                    Next J
    ActiveCell.Interior.ColorIndex = 6
 Dim Ws As Worksheet
    Set Ws = Application.Workbooks("TH_chitiet.xls").Worksheets("TH_chitiet")
    With Ws.[B1000].End(xlUp)(2)
        If .Row = 7 Then
            .Offset(, -1) = 1
        Else
            .Offset(, -1) = 1 + Application.WorksheetFunction.Max(Ws.Range((Ws.[B5]), (Ws.[B10000].End(xlUp))).Offset(, -1))
        End If
    End With
    Ws.[B1000].End(xlUp)(2).Resize(K, 7) = Mg
    Application.Workbooks("TH_chitiet").Save
    Ws.Select
   
    End If
    End If
    Set Ws = Nothing
Exit Sub
Lôi:  If (Mg(K, 2) = Empty) Or (Mg(K, 3) = Empty) Or (Mg(K, 4) = Empty) Or (Mg(K, 5) = Empty) Then
         UserForm2.Show
      End If
End Sub

3- Thêm các đối số thích hợp cho Sub AAA:
3a- Truyền biến Cell được chọn, để khỏi sửa code, ta đặt tên biến là Target
Private Sub AAA(ByVal Target As Range)
3b- Truyền biến vùng giao [vd đó là Range([K132], [K10000].End(xlUp))], đặt tên là Giao1
Private Sub AAA(ByVal Target As Range, ByVal Giao1 As Range)
3c- Truyền biến không giao [vd là Range([AI132], [AI10000].End(xlUp))] đặt tên là Giao2
Mã: Chọn tất cả
Private Sub AAA(ByVal Target As Range, ByVal Giao1 As Range, ByVal Giao2 As Range)

4- Sửa code bên dưới:
vd dòng 1 = ok
Dim Vung, I, J, kK, Mg, TachDm, TachMau, Tong, K, A, B
Dòng 2 cần sửa:
If Not Intersect(Target, Range([K132], [K10000].End(xlUp))) Is Nothing Or Not Intersect(Target, Range([AI132], [AI10000].End(xlUp))) Is Nothing Then
* Target giữ nguyên
* Range([K132], [K10000].End(xlUp)) thay bằng Giao1
Range([AI132], [AI10000].End(xlUp)) thay bằng Giao2
If Not Intersect(Target, Giao1) Is Nothing Or Not Intersect(Target, Giao2) Is Nothing Then

Vậy ta đã có macro mới: (ghi đoạn đầu)
Mã: Chọn tất cả
Private Sub AAA(ByVal Target As Range, ByVal Giao1 As Range, ByVal Giao2 As Range)
Dim Vung, I, J, kK, Mg, TachDm, TachMau, Tong, K, A, B
    If Not Intersect(Target, Giao1) Is Nothing Or Not Intersect(Target, Giao2) Is Nothing Then
'..... vv


4- Sử dụng macro AAA:
Vì sự kiện worksheet_selectionchange rất quý: cứ nhấn vào Cell nào được chọn thì sub sẽ thi hành, nên ta chọn nó để gọi Sub AAA:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
End Sub

Ta gọi Sub AAA trong đó như sau:
Đối số Target, ta đã có.
Đói số Giao1:
Dim VungGiao1 as range
Vunggiao1 = Range([K132], [K10000].End(xlUp))
tương tự vunggiao2:
Dim VungGiao2 as range
Vunggiao2 = Range([AI132], [AI10000].End(xlUp))
Kết quả:
Mã: Chọn tất cả
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim VungGiao1 as range
Vunggiao1 = Range([K132], [K10000].End(xlUp))
Dim VungGiao2 as range
Vunggiao2 = Range([AI132], [AI10000].End(xlUp))
   
AAA Target, VungGiao1, VungGiao2
End Sub


Hiệu quả:
a- Bạn nhấn vào các cell từ K132 trở đi, sẽ thấy tác dụng code trong sub AAA làm việc
b- Bạn có thể đổi vị trí vùngGiao khác, vd: có bảng khác giống thế tuốt bên cột AA, vẫn dùng VungGiao2

Mã: Chọn tất cả
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim VungGiaoKhac as range
VungGiaoKhac = Range([AA132], [AA10000].End(xlUp))
Dim VungGiao2 as range
Vunggiao2 = Range([AI132], [AI10000].End(xlUp))
   AAA Target, VungGiaoKhac, VungGiao2
End Sub


OK chưa?
===========
Đoạn:
Lôi: If (Mg(K, 2) = Empty) Or (Mg(K, 3) = Empty) Or (Mg(K, 4) = Empty) Or (Mg(K, 5) = Empty) Then
UserForm2.Show
End If

nên bỏ hết, đấy là nói cho bạn rõ, thực tế, bạn chỉ cần ghi UserForm2.Show là đủ!
Mã: Chọn tất cả
 '''   
Set Ws = Nothing
Exit Sub
Lôi:   UserForm2.Show
End Sub
o0o--truongphu--o0o

.........
Ghé thăm:
Chuyện Linh Tinh
Hình đại diện của thành viên
truongphu
VIP
VIP
 
Bài viết: 4721
Ngày tham gia: Chủ nhật 04/11/2007 10:57 am
Đến từ: Cam Đức, Khánh hòa
Đã cảm ơn: 13 lần
Được cảm ơn: 470 lần

Re: đổi từ sự kiện selectionchange thành public sub (macro)

Gửi bàigửi bởi tuanbonus » Thứ 3 24/07/2012 12:34 am

Code của bạn (bài đầu) dùng rất khá..
Vậy cớ sao hướng dẫn như thế bạn còn bí?


Cám ơn thầy TruongPhu, thầy không làm giúp khúc này em mò chắc đến cuối năm!
tuanbonus
Thành viên chính thức
Thành viên chính thức
 
Bài viết: 14
Ngày tham gia: Thứ 4 20/06/2012 2:03 pm
Đã cảm ơn: 8 lần
Được cảm ơn: 0 lần

Re: đổi từ sự kiện selectionchange thành public sub (macro)

Gửi bàigửi bởi tuanbonus » Thứ 4 25/07/2012 8:44 am

hi anh TruongPhu, em làm theo cách này nhưng macro chỉ được ở file gốc (ý là làm việc trên file gốc), khi chuyển qua (*.xla) đưa vào add-ins móc ra sữ dụng cho workbook khác cũng có định dạng giống vậy & cũng xuất dữ liệu đúng đường dẫn, thì selectionchange không nhận dạng được macro AAA. giải quyết vấn đề này sao hả anh?
tuanbonus
Thành viên chính thức
Thành viên chính thức
 
Bài viết: 14
Ngày tham gia: Thứ 4 20/06/2012 2:03 pm
Đã cảm ơn: 8 lần
Được cảm ơn: 0 lần

Re: đổi từ sự kiện selectionchange thành public sub (macro)  Chủ đề đã được giải quyết

Gửi bàigửi bởi truongphu » Thứ 4 25/07/2012 9:13 pm

tuanbonus đã viết:sữ dụng cho workbook khác cũng có định dạng giống vậy & cũng xuất dữ liệu đúng đường dẫn, thì selectionchange không nhận dạng được macro AAA.


Có rất nhiều nguyên do
1- Chung: cách sử dụng Addin cho VBA: Bạn xem bài sau để Add-In đưa vào References của VBA
How to Use Your Excel Add-In Functions in VBA

2- Trong Sub AAA nêu trên, một số đoạn code cũng không phải là code chung, vd:
...: Mg(K, 6) = Range("AJ108"): Mg(K, 7) = Range("P112")
Bạn thấy đấy, các địa chỉ range trên cố định là không tốt; chưa kể các đoạn code bên dưới khi bạn gọi ra file TH_chitiet...
Do đó bạn cần tinh chỉnh lại
Tôi chỉ nêu chung chung hướng dẫn tổng quát, vấn đề cụ thể của bạn, quả thật tôi không nắm rõ!
o0o--truongphu--o0o

.........
Ghé thăm:
Chuyện Linh Tinh
Hình đại diện của thành viên
truongphu
VIP
VIP
 
Bài viết: 4721
Ngày tham gia: Chủ nhật 04/11/2007 10:57 am
Đến từ: Cam Đức, Khánh hòa
Đã cảm ơn: 13 lần
Được cảm ơn: 470 lần

Re: đổi từ sự kiện selectionchange thành public sub (macro)

Gửi bàigửi bởi tuanbonus » Thứ 4 01/08/2012 10:22 am

dear anh chị & anh TruongPhu.
giúp tôi một khúc code nữa, tôi muốn tạo một userform gồm 1 listbox, 1 cmdAddfile, 1 cmdXoafile, 1 cmdClearfile.
1./ cmdAddfile. Khi add một file or nhiều files bất kỳ ở một folder bất kỳ thì sẽ nạp vào listbox của userform đồng thời copy đoạn code dạng chuỗi:
Mã: Chọn tất cả
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim VungGiao1 as range
Vunggiao1 = Range([K132], [K10000].End(xlUp))
Dim VungGiao2 as range
Vunggiao2 = Range([AI132], [AI10000].End(xlUp))
   
AAA Target, VungGiao1, VungGiao2
End Sub

vào tất cả các codesheet con của file đó và hiện hành luôn để là việc.
2./ cmdXoafile. Khi trong listbox nhiều files được add mình muốn chọn xoá 1 file bất kỳ thì cũng xoá luôn đoạn code đã được gắn vào các codesheet của file đó & close file luôn.
3./ cmdClearfile. Cũng giống #2 nhưng clear all files ra khỏi listbox & close all luôn.

có đính kèm file anh chị & anh TruongPhu giúp tôi, xin chân thàh cảm ơn.

Thật tình tôi nhờ vả thì nhiều mà chưa có cơ hội offline cùng anh chị trong câu lạc bộ để giao học hỏi hay ủng hộ gì cả mong một ngày gần nhất tôi sẽ được phép làm điều đó. Còn khi học hỏi anh chị tôi đạt được cơ bản nhất định, tôi cũng hổ trợ để chia sẽ những thành viên mới giống như tôi bây giờ.
Bạn không được cấp phép để xem tập tin đính kèm trong bài viết này.
tuanbonus
Thành viên chính thức
Thành viên chính thức
 
Bài viết: 14
Ngày tham gia: Thứ 4 20/06/2012 2:03 pm
Đã cảm ơn: 8 lần
Được cảm ơn: 0 lần

Re: đổi từ sự kiện selectionchange thành public sub (macro)

Gửi bàigửi bởi vietteiv » Thứ 4 01/08/2012 12:17 pm

trước khi chuyển sang câu hỏi khác, bạn xác nhận lại vấn đề đầu tiên về cái macro đã xong chưa?

p/s: chưa thấy bạn nhắc đến việc đã kiểm tra có cho phép macro chạy hay ko?
khi mở 1 file có macro mặc định excel sẽ hiện thông báo hỏi enable hay disable --> chỉ lưu thiết lập trên chính file gốc đó mà thôi

bạn vào option \ macro settings:
- chọn enable all macro
- chọn trust access to the VBA project object model

test lại rồi thông báo kết quả có thực hiện được hay ko
Phần mềm Quản lý thông tin dự án (PMS), Quản lý doanh nghiệp (EMS)
http://www.dong-tay.com
Hình đại diện của thành viên
vietteiv
Quản trị
Quản trị
 
Bài viết: 1289
Ngày tham gia: Thứ 7 10/02/2007 12:17 am
Đến từ: Cung cấp giải pháp quản lý doanh nghiệp, dự án, tư vấn xây dựng
Đã cảm ơn: 6 lần
Được cảm ơn: 59 lần

Re: đổi từ sự kiện selectionchange thành public sub (macro)

Gửi bàigửi bởi tuanbonus » Thứ 4 01/08/2012 1:30 pm

hi Vietteiv,
1./ Macro chạy tốt rồi, nhưng muốn macro chạy các file khác mình phải copy thủ công đoạn code (worksheet_selectionchange) trên vào các sheets của file đó mới gọi được macro.
2./ Câu hỏi mới mình đã tạo cái form rồi còn code thì quá khó, mình nhờ anh em giúp.

cám ơn nhiều.
tuanbonus
Thành viên chính thức
Thành viên chính thức
 
Bài viết: 14
Ngày tham gia: Thứ 4 20/06/2012 2:03 pm
Đã cảm ơn: 8 lần
Được cảm ơn: 0 lần

Re: đổi từ sự kiện selectionchange thành public sub (macro)

Gửi bàigửi bởi truongphu » Thứ 5 02/08/2012 9:54 pm

tuanbonus đã viết:đồng thời copy đoạn code dạng chuỗi vào tất cả các codesheet con của file đó


Đây là nội dung đưa code (macro) vào Module hay workbook, worksheet... của một file Excel
Để làm điều nầy không dễ như bạn tưởng!

Bạn phải đi vào lớp VBE và các thành phần dưới nó
vd: Application.VBE.ActiveVBProject.VBComponents...
(Application là biến đối tượng Excel.Application)

Sau đó bạn mới nạp code vào từng dòng...
mà như bạn... :-/ chưa quen làm sao mà mần? =((

====

Tôi bày cách khác thích hợp cho bạn: (và bạn phải search thêm trên gugồn)
1- Chép đoạn code Worksheet_SelectionChange vào Notepad
2- Lưu dưới đuôi .bas, vd C:\1.bas
3- Lệnh ghi vào module của file excel mới
Mã: Chọn tất cả
AAA.VBE.ActiveVBProject.VBComponents.Import "C:\1.bas"

Trong đó AAA là biến Excel.Application đã mở file excel mới cần tuồn code trên vào.

Thế thôi, chúc bạn thành công

====
ghi chú: để tuồn tự động macro vào file excel
phải làm như anh vieteiv nói trên:
Bạn không được cấp phép để xem tập tin đính kèm trong bài viết này.
o0o--truongphu--o0o

.........
Ghé thăm:
Chuyện Linh Tinh
Hình đại diện của thành viên
truongphu
VIP
VIP
 
Bài viết: 4721
Ngày tham gia: Chủ nhật 04/11/2007 10:57 am
Đến từ: Cam Đức, Khánh hòa
Đã cảm ơn: 13 lần
Được cảm ơn: 470 lần

Re: đổi từ sự kiện selectionchange thành public sub (macro)

Gửi bàigửi bởi truongphu » Thứ 3 07/08/2012 7:11 am

o0o--truongphu--o0o

.........
Ghé thăm:
Chuyện Linh Tinh
Hình đại diện của thành viên
truongphu
VIP
VIP
 
Bài viết: 4721
Ngày tham gia: Chủ nhật 04/11/2007 10:57 am
Đến từ: Cam Đức, Khánh hòa
Đã cảm ơn: 13 lần
Được cảm ơn: 470 lần


Quay về Visual Basic for Application (VBA)

Ai đang trực tuyến?

Đang xem chuyên mục này: Không có thành viên nào đang trực tuyến1 khách