doveandrose
hello
- Tham gia
- 3/7/09
- Bài viết
- 2,375
- Được thích
- 2,264
Chào các bạn diễn đàn GPE
lâu nay chúng ta thường gặp rất nhiều cửa sổ Dialog , hoặc Menu hệ thống của Excel
Nhưng có bao giờ các bạn thử tìm cách lấy nội dung trên các cửa sổ đó ?
Tôi đã từng đặt vấn đề này , và tôi chỉ nhận được câu trả lời "không có manh mối"
Cái Bill dành cho chúng ta chỉ là
để xem . Như kiểu muốn nói với chúng ta là : Chỉ được xem , cấm sờ vào hiện vật
Điều này làm tôi ức chế đã lâu , tôi lục lọi các nơi , và cuối cùng tôi cũng tìm ra cách truy cập vào các cửa sổ ấy :
Dùng UIAutomation
với UIAutomation , tôi tin rằng chúng ta có thể
Truy cập vào các Dialog hệ thống để lấy nội dung trong ấy ra
Truy câp vào các Menu ( Như menu Auto Filter ) để lấy nội dung trên Menu
Bắt sự kiện Cell TextChange khi Đang ở chế độ Edit Mode
Chúng ta sẽ không nói nhiều về Lý thuyết mà đi thẳng vào áp dụng đầu tiên :
Lấy nội dung trên Dialog Select Sheet của Excel : Đồng nghĩa với việc lấy các Sheet trên File đang đóng hoặc mở chính xác nhất
khi làm việc cùng UIAutomation thì bắt buộc phải check vào thư viện UIAutomationClient
nói 1 chút về các Object của UIAutomation
CUIAutomation : đây là cái lò sản xuất ra các Object khác , đồng thời cung cấp các phương thức để làm việc với các Object UIAutomation
IUIAutomationElement : đây là thành phần cơ bản đại diện cho mọi đối tượng UI của Hệ điều hành , từ 1 cửa sổ ứng dụng , hay 1 control , 1 menu , 1 toolTip,...
kể cả những Control nhỏ bé không được cấp chỉ số HWND . Chúng ta sẽ làm việc chủ yếu với Object này
Xác định Cửa Sổ Excel
Khi Dialog Select Sheet hiện ra thì có Danh sách Sheet nằm sẵn trong Control Listbox của Dialog để chúng ta lấy không ? rất tiếc là không
Vì Excel đang làm nhiệm vụ chạy Code rất bí mật để lấy Danh sách Sheet, khi nào có kết quả thì mới dán lên Dialog sau (bất đồng bộ)
Vậy phải làm sao ?
Chúng ta nhìn thấy rằng khi đã có Danh sách Sheet thì Dialog tự động Select item đầu tiên của Listbox
thông thường khi viết Code , chúng ta AddItem cho Listbox xong xuôi thì mới nghĩ đến chuyện Select Item nào
Vậy suy bụng ta ra bụng người , khi Select Item có nghĩa là Đã AddItem xong
Ta sẽ bắt sự kiện Selection trên Listbox của Dialog
Để làm được điều này UIAutomation cung cấp Interface IUIAutomationEventHandler
Thực hiện :
Các bạn tạo mới 1 Class Module
gõ vào Class lệnh này
Implements IUIAutomationEventHandler
gõ Enter
bây giờ trong Combobox góc trên bên trái bạn bấm vào rồi chọn IUIAutomationEventHandler
nó sẽ tự động hiện ra
Private Sub IUIAutomationEventHandler_HandleAutomationEvent(ByVal sender As UIAutomationClient.IUIAutomationElement, ByVal eventId As Long)
đây là nơi chúng ta thực hiện Code khi Sự kiện Selection xảy ra
Bạn Click vào Property của Class Module này
Nó đang ở Chế độ Private
Sửa lại thành PublicNotCreateAble
Save
Quay lại Sub , trước khi Dialog hiện ra , ta phải gắn Track sự kiện
UIA_SelectionItem_ElementSelectedEventId : mã số cho biết sẽ Track sự kiện SelectionItem
TreeScope_Descendants : nói rằng sẽ Track sự kiện trên tất cả Control con cháu của cửa sổ Excel
Bây giờ khi sự kiện SelectionItem xảy ra thì ta làm gì đây ?
Ta làm quen các Object mới
IUIAutomationTreeWalker : giúp truy tìm các thành phần cha hoặc con của IUIAutomationElement
khi Sự kiện Selection xảy ra thì nó được tính cho Control ListItem của Listbox vì vậy Sender là 1 ListItem
ta gọi GetParentElement 2 lần để tìm đến cửa sổ cha
IUIAutomationCondition : thiết lập điều kiện để truy tìm các thành phần IUIAutomationElement
có rất nhiều loại Condition có thể thiết lập , như truy theo Name ( caption của 1 cửa sổ ), ClassName , theo ControlType,...
ở đây là dùng truy theo ControlType
TreeScope : tầm vực tìm kiếm
TreeScope_Descendants : tìm ở tất cả vùng con cháu dòng họ của 1 IUIAutomationElement
TreeScope_Children : chỉ tìm thành phần con trực tiếp của 1 IUIAutomationElement
TreeScope_Element : trỏ đến chính IUIAutomationElement đó
khi gọi
ta đã có Danh sách các ListItem của Listbox
Ta dùng Thuộc tính CurrentName để lấy giá trị Text của các ListItem
Cuối cùng ta cần Force Click nút OK trên Dialog để đóng nó lại
Gán kết quả ra Sheet
Gỡ bỏ mọi Track sự kiện ra khỏi Cửa sổ Excel
Tôi đã trình bày các bước cơ bản nhất để tương tác với các cửa sổ Dialog hệ thống của Excel
Chắc chắn còn nhiều thiếu sót vì chỉ trình bày ở dạng giới thiệu
Còn rất nhiều vấn đề chúng ta cần bàn thêm , mong được trao đổi với các bạn
Trong lần tới chúng ta sẽ nói về việc :
Lấy Nội dung trên Menu AutoFilter của Excel
Hẹn gặp lại các bạn .
lâu nay chúng ta thường gặp rất nhiều cửa sổ Dialog , hoặc Menu hệ thống của Excel
Nhưng có bao giờ các bạn thử tìm cách lấy nội dung trên các cửa sổ đó ?
Tôi đã từng đặt vấn đề này , và tôi chỉ nhận được câu trả lời "không có manh mối"
Cái Bill dành cho chúng ta chỉ là
Mã:
Application.Dialogs(dialogID).Show
Điều này làm tôi ức chế đã lâu , tôi lục lọi các nơi , và cuối cùng tôi cũng tìm ra cách truy cập vào các cửa sổ ấy :
Dùng UIAutomation
với UIAutomation , tôi tin rằng chúng ta có thể
Truy cập vào các Dialog hệ thống để lấy nội dung trong ấy ra
Truy câp vào các Menu ( Như menu Auto Filter ) để lấy nội dung trên Menu
Bắt sự kiện Cell TextChange khi Đang ở chế độ Edit Mode
Chúng ta sẽ không nói nhiều về Lý thuyết mà đi thẳng vào áp dụng đầu tiên :
Lấy nội dung trên Dialog Select Sheet của Excel : Đồng nghĩa với việc lấy các Sheet trên File đang đóng hoặc mở chính xác nhất
khi làm việc cùng UIAutomation thì bắt buộc phải check vào thư viện UIAutomationClient
nói 1 chút về các Object của UIAutomation
CUIAutomation : đây là cái lò sản xuất ra các Object khác , đồng thời cung cấp các phương thức để làm việc với các Object UIAutomation
IUIAutomationElement : đây là thành phần cơ bản đại diện cho mọi đối tượng UI của Hệ điều hành , từ 1 cửa sổ ứng dụng , hay 1 control , 1 menu , 1 toolTip,...
kể cả những Control nhỏ bé không được cấp chỉ số HWND . Chúng ta sẽ làm việc chủ yếu với Object này
Xác định Cửa Sổ Excel
Mã:
Set myApp = cUI.ElementFromHandle(ByVal Application.Hwnd)
Khi Dialog Select Sheet hiện ra thì có Danh sách Sheet nằm sẵn trong Control Listbox của Dialog để chúng ta lấy không ? rất tiếc là không
Vì Excel đang làm nhiệm vụ chạy Code rất bí mật để lấy Danh sách Sheet, khi nào có kết quả thì mới dán lên Dialog sau (bất đồng bộ)
Vậy phải làm sao ?
Chúng ta nhìn thấy rằng khi đã có Danh sách Sheet thì Dialog tự động Select item đầu tiên của Listbox
thông thường khi viết Code , chúng ta AddItem cho Listbox xong xuôi thì mới nghĩ đến chuyện Select Item nào
Vậy suy bụng ta ra bụng người , khi Select Item có nghĩa là Đã AddItem xong
Ta sẽ bắt sự kiện Selection trên Listbox của Dialog
Để làm được điều này UIAutomation cung cấp Interface IUIAutomationEventHandler
Thực hiện :
Các bạn tạo mới 1 Class Module
gõ vào Class lệnh này
Implements IUIAutomationEventHandler
gõ Enter
bây giờ trong Combobox góc trên bên trái bạn bấm vào rồi chọn IUIAutomationEventHandler
nó sẽ tự động hiện ra
Private Sub IUIAutomationEventHandler_HandleAutomationEvent(ByVal sender As UIAutomationClient.IUIAutomationElement, ByVal eventId As Long)
đây là nơi chúng ta thực hiện Code khi Sự kiện Selection xảy ra
Bạn Click vào Property của Class Module này
Nó đang ở Chế độ Private
Sửa lại thành PublicNotCreateAble
Save
Quay lại Sub , trước khi Dialog hiện ra , ta phải gắn Track sự kiện
Mã:
cUI.AddAutomationEventHandler UIA_SelectionItem_ElementSelectedEventId, myApp, _
TreeScope_Descendants, Nothing, New Class1
UIA_SelectionItem_ElementSelectedEventId : mã số cho biết sẽ Track sự kiện SelectionItem
TreeScope_Descendants : nói rằng sẽ Track sự kiện trên tất cả Control con cháu của cửa sổ Excel
Bây giờ khi sự kiện SelectionItem xảy ra thì ta làm gì đây ?
Ta làm quen các Object mới
IUIAutomationTreeWalker : giúp truy tìm các thành phần cha hoặc con của IUIAutomationElement
khi Sự kiện Selection xảy ra thì nó được tính cho Control ListItem của Listbox vì vậy Sender là 1 ListItem
Mã:
Set myForm = walker.GetParentElement(sender) 'Listbox
Set myForm = walker.GetParentElement(myForm) 'Dialog Select Sheet
ta gọi GetParentElement 2 lần để tìm đến cửa sổ cha
IUIAutomationCondition : thiết lập điều kiện để truy tìm các thành phần IUIAutomationElement
có rất nhiều loại Condition có thể thiết lập , như truy theo Name ( caption của 1 cửa sổ ), ClassName , theo ControlType,...
ở đây là dùng truy theo ControlType
Mã:
Set condition = cUI.CreatePropertyCondition(UIA_ControlTypePropertyId, UIA_ListItemControlTypeId)
TreeScope : tầm vực tìm kiếm
TreeScope_Descendants : tìm ở tất cả vùng con cháu dòng họ của 1 IUIAutomationElement
TreeScope_Children : chỉ tìm thành phần con trực tiếp của 1 IUIAutomationElement
TreeScope_Element : trỏ đến chính IUIAutomationElement đó
khi gọi
Mã:
Set elemColl = myForm.FindAll(TreeScope_Descendants, condition)
Ta dùng Thuộc tính CurrentName để lấy giá trị Text của các ListItem
Mã:
If elemColl.Length > 0 Then
ReDim rsSheetNames(1 To elemColl.Length, 1 To 1)
For r = 1 To elemColl.Length Step 1
rsSheetNames(r, 1) = elemColl.GetElement(r - 1).CurrentName
Next
End If
Mã:
Set condition = cUI.CreatePropertyCondition(UIA_NamePropertyId, "OK")
Set OKbtn = myForm.FindFirst(TreeScope_Children, condition)
Set clickPattern = OKbtn.GetCurrentPattern(UIA_InvokePatternId)
clickPattern.Invoke ' send CLick
Gán kết quả ra Sheet
Mã:
Sheet1.Range("B2:B1000").ClearContents
If IsArray(rsSheetNames) Then
Sheet1.Range("B2").Resize(UBound(rsSheetNames)).Value = rsSheetNames
End If
Sheet1.Range("C3").ClearContents
Gỡ bỏ mọi Track sự kiện ra khỏi Cửa sổ Excel
Mã:
cUI.RemoveAllEventHandlers
Set cUI = Nothing
Tôi đã trình bày các bước cơ bản nhất để tương tác với các cửa sổ Dialog hệ thống của Excel
Chắc chắn còn nhiều thiếu sót vì chỉ trình bày ở dạng giới thiệu
Còn rất nhiều vấn đề chúng ta cần bàn thêm , mong được trao đổi với các bạn
Trong lần tới chúng ta sẽ nói về việc :
Lấy Nội dung trên Menu AutoFilter của Excel
Hẹn gặp lại các bạn .