VBA Web : làm sao chọn các listbox trên web liên quan đến nhau? (Tỉnh/quận-huyện/phường-xã)

Liên hệ QC

phanminhphuonghl

Thành viên mới
Tham gia
8/12/20
Bài viết
6
Được thích
0
Chào mọi người!

Mình có viết một đoạn mã để khai báo y tế trên trang web https://tokhaiyte.vn
Mình chỉ còn 1 chỗ là chưa thực hiện được như hình: chọn Tỉnh sau đó mới hiện danh sách để chọn được quận/huyện và tiếp tục mới có danh sách để chọn phường xã.
Mọi người vui lòng chỉ giúp mình có thể chọn được 3 listbox này bằng VBA không ạ.

Xin cám ơn!

</div> </div> <div class="col-md-4 col-sm-4 col-xs-12 " > <div class="form-group " > <label >Quận / huyện </label> <select id="input34291" name="fields[afterIsolationStayDistrictId]" class="form-control" data-x-cascade="fields[afterIsolationStayProvinceId]:provinceId" > <option value="">-Chọn-</option> </select> </div> </div> <div class="col-md-4 col-sm-4 col-xs-12 " > <div class="form-group " > <label >Phường / xã </label>

Mã:
Sub VbaWeb()

  Dim oIE As Object         'InternetExplorer.Application
  Dim btnInput As Object    'MSHTML.HTMLInputElement
  Dim ieDoc As Object       'MSHTML.HTMLDocument
  Dim sURL As String

'On Error Resume Next

Set oIE = CreateObject("InternetExplorer.Application")
    sURL = "https://tokhaiyte.vn"

With oIE
    .Navigate sURL
    .Visible = True
    Do While .Busy Or .ReadyState <> 4: DoEvents: Loop                              'Loop until the page finishes loading
End With

Set ieDoc = oIE.Document

'cac doan code khac

ieDoc.getElementsByname("fields[provinceId]")(0).Value = "5657e3ab7f8b9a117c8b4575" '=> Listbox Tinh OK
ieDoc.getElementsByname("fields[provinceId]")(0).selectedindex = 49 'Tuong tu Ok QUANG NINH

ieDoc.getElementsByname("fields[districtId]")(0).selectedindex = 3 ' chon Thanh Pho Cam Pha khong duoc
ieDoc.getElementsByname("fields[wardId]")(0).selectedindex = 11 ' chon Phuong Cam Trung khong duoc


  Set oIE = Nothing
  Set ieDoc = Nothing
  Set btnInput = Nothing

End Sub
3 listbox.jpg
 

File đính kèm

  • VBA web - select 3 listbox.xlsm
    18.7 KB · Đọc: 16
Lần chỉnh sửa cuối:
chọn được 3 listbox này bằng VBA
Mình điền cái giá trị Value vào là được.

Lưu ý rằng: Sau khi chọn được 1 cái thì phải đợi phía server trả về kết quả, rồi lấy theo object gốc - ở đây là oIE thì mới có cái mà điền vào.

1607408357626.png

Nếu không quen code thì nên chọn phần mềm hỗ trợ việc này, điển hình là UiPath. Với bài này thì đọc một chút hướng dẫn là làm được.
 
Upvote 0
Mình điền cái giá trị Value vào là được.

Lưu ý rằng: Sau khi chọn được 1 cái thì phải đợi phía server trả về kết quả, rồi lấy theo object gốc - ở đây là oIE thì mới có cái mà điền vào.

View attachment 250791

Nếu không quen code thì nên chọn phần mềm hỗ trợ việc này, điển hình là UiPath. Với bài này thì đọc một chút hướng dẫn là làm được.
Bạn có thể giúp cho mình tham khảo đoạn code cho ví dụ này không vì mình chỉ muốn tích hợp vào file excel của mình (các mục khác trong trang web tokhaiyte.vn mình đã làm được):
1) chọn tỉnh Quảng Ninh; chờ hệ thống trả về kết quả cho listbox quận/huyện
2) quận/huyện chọn Tp Cẩm Phả ; chờ hệ thống trả về kết quả cho listbox xã phường
3) chọn phường Cẩm Trung
 
Upvote 0
Mình điền cái giá trị Value vào là được.

Lưu ý rằng: Sau khi chọn được 1 cái thì phải đợi phía server trả về kết quả, rồi lấy theo object gốc - ở đây là oIE thì mới có cái mà điền vào.
...
Vụ này trong ngôn ngữ lập trình giao diện gọi nó là Drill Down (đi vào tầng kế tiếp). Drop Down hay ListBox là tiếng chỉ đơn độc 1 tầng.
 
Upvote 0
Mình tự làm rồi đó thôi.

1607409949127.png

Chờ đợi kết quả về:
- Một là tự thử nghiệm sau khi dùng tay ấn chọn thì sau bao nhiêu mili giây, bao nhiêu phút... thì ô bên cạnh chọn được? Vậy thì cho code chờ từng đó thời gian, dùng wait hoặc sleep API
- Code một sub/ function gì đó kiểm tra việc này. Tự suy diễn khi nào thì server trả kết quả theo cách trên.

Người ta bảo cụ thể rồi:
1607409966880.png

Vậy thay vì dùng ieDoc kia thì mình cái oIE.Document

Mình cứ đọc --- thật --- chậm --- rồi làm theo là được liền.
 
Upvote 0
Dưới cùng của cái form có nguyên cái mục bắt nhập CAPTCHA mà có bác bảo dùng phần mềm tự động làm thì đúng tài thật. --=0

Phân tích dữ liệu trao đổi giữa IE với host khi xẩy ra sự kiện chọn tỉnh theo id (5657e3ab7f8b9a117c8b456e) thì ta thấy IE có hành vi này:
Request Method: POST​
Với data là như thế này:
type: Form.Select​
class: form-control​
name: fields[afterIsolationStayDistrictId]​
simple: 1​
description: -Chọn-​
service: Content.Region.selectDistricts​
value:​
provinceId: 5657e3ab7f8b9a117c8b456e
data-x-cascade: fields[afterIsolationStayProvinceId]: provinceId​
totalItems: 0​
inputCount: 66155​
multiLanguage: false​
currency: VND​
mid: 11​
site: 2001432​
securityToken: 573b0fa7957e3d1b6dabb77c7edbe401a12ffea0129cbf97d8adb90f9f27f89d​

Tôi quyết định thử làm một cái form tự tạo rồi truy vấn thử xem kết quả tìm huyện theo tỉnh thế nào. Vì lười biếng nên tôi vứt bỏ gần hết data mẫu mà chỉ giữ lại:
provinceId: 5657e3ab7f8b9a117c8b456e​
Kết quả nhận được là như thế này:
{"items":[{"id":"5657e3ab7f8b9a117c8b45e9","title":"\u0110i\u1ec7n Bi\u00ean"},{"id":"5657e3ab7f8b9a117c8b45ea","title":"\u0110i\u1ec7n Bi\u00ean \u0110\u00f4ng"},{"id":"5657e3ab7f8b9a117c8b45e3","title":"Th\u00e0nh ph\u1ed1 \u0110i\u1ec7n Bi\u00ean Ph\u1ee7"},{"id":"5657e3ac7f8b9a117c8b48b9","title":"M\u01b0\u1eddng \u1ea2ng"},{"id":"5657e3ab7f8b9a117c8b45e6","title":"M\u01b0\u1eddng Ch\u00e0"},{"id":"5657e3ab7f8b9a117c8b45e4","title":"Th\u1ecb X\u00e3 M\u01b0\u1eddng Lay"},{"id":"5657e3ab7f8b9a117c8b45e5","title":"M\u01b0\u1eddng Nh\u00e9"},{"id":"5657e3ac7f8b9a117c8b489a","title":"N\u1eadm P\u1ed3"},{"id":"5657e3ab7f8b9a117c8b45e7","title":"T\u1ee7a Ch\u00f9a"},{"id":"5657e3ab7f8b9a117c8b45e8","title":"Tu\u1ea7n Gi\u00e1o"}],"totalItems":10}

Lại ngứa ngáy tiếp, tôi thử sử dụng method=GET với cái link: https://tokhaiyte.vn/api/Content/Region/selectDistricts?provinceId=5657e3ab7f8b9a117c8b456e thì cũng thu được đống chữ ở trên. Tương tự với anh phường, tôi lại thử: https://tokhaiyte.vn/api/Content/Region/selectWards=.... cũng ra đống chữ.
Đến phần này rồi thì xin nhường các cụ yêu bảng mã chữ quốc ngữ (Tiếng Việt) giải quyết nốt :pray:
 
Lần chỉnh sửa cuối:
Upvote 0
Người ra kêu chọn trên biểu mẫu (vì làm nhiều, chọn cho nhanh chẳng hạn), đâu lại kéo sang nhập với cả vượt mã captcha.

Bẻ lái ngọt như thịt heo hầm. Híc.
 
Upvote 0
Người ra kêu chọn trên biểu mẫu (vì làm nhiều, chọn cho nhanh chẳng hạn), đâu lại kéo sang nhập với cả vượt mã captcha.

Bẻ lái ngọt như thịt heo hầm. Híc.
Cho hỏi phần mềm đó có thể chọn theo tỉnh bất kỳ không ạ? Trong danh sách nhập, có người từ tỉnh A, người từ tỉnh B... thì có phần mềm nào tự động đọc ra rồi tự chọn đúng không?
 
Upvote 0
Mình tự làm rồi đó thôi.

View attachment 250797

Chờ đợi kết quả về:
- Một là tự thử nghiệm sau khi dùng tay ấn chọn thì sau bao nhiêu mili giây, bao nhiêu phút... thì ô bên cạnh chọn được? Vậy thì cho code chờ từng đó thời gian, dùng wait hoặc sleep API
- Code một sub/ function gì đó kiểm tra việc này. Tự suy diễn khi nào thì server trả kết quả theo cách trên.

Người ta bảo cụ thể rồi:
View attachment 250798

Vậy thay vì dùng ieDoc kia thì mình cái oIE.Document

Mình cứ đọc --- thật --- chậm --- rồi làm theo là được liền.
Chọn Tỉnh bằng tay thì hiện lên danh sách quận huyện, nhưng gán giá trị Tỉnh bằng code VBA (thêm cả application.wait) thì web không có lên danh sách quận huyện nên thử mãi không được ở bước này. Vui lòng hỗ trợ.
Bài đã được tự động gộp:

Cho hỏi phần mềm đó có thể chọn theo tỉnh bất kỳ không ạ? Trong danh sách nhập, có người từ tỉnh A, người từ tỉnh B... thì có phần mềm nào tự động đọc ra rồi tự chọn đúng không?
Mình thường xuyên phải khai báo cho 1 danh sách khoảng 25 người/lần. mình hỏi để làm 1 trường hợp này tự động điền sau đó điền Capcha ở cuối và update là xong, rồi các bước tương tự của những người khác dùng vòng lặp không có gì khó. Chỉ có cái là bây giờ không biết làm sao chọn được 3 cái listbox Tỉnh/Quận-huyện/xã-phường , tức là đi vào tầng kế tiếp.3 listbox.jpg
 
Lần chỉnh sửa cuối:
Upvote 0
Trên IE thực, khi bạn thay đổi giá trị combox thì sẽ phát sinh ra một event, và cái event này kích hoạt một thủ tục request dữ liệu như tôi phân tích ở trên.
Vấn đề là khi bạn chạy dòng lệnh:
PHP:
ieDoc.getElementsByname("fields[provinceId]")(0).Value = "5657e3ab7f8b9a117c8b4575" '=> Listbox Tinh OK
hoặc
ieDoc.getElementsByname("fields[provinceId]")(0).selectedindex = 49 'Tuong tu Ok QUANG NINH
thì nó có kích hoạt event tôi nêu không? Giả sử có phát sinh event thì nếu request dữ liệu được thực hiện trong một thread riêng của IE thì bạn không thể thực hiện được ngay lập tức cái dòng lệnh kế tiếp là
PHP:
ieDoc.getElementsByname("fields[districtId]")(0).selectedindex = 3
Muốn thực hiện dòng lệnh này thì bạn phải chờ IE hoàn thành xong request dữ liệu và xây dựng lại anh combox. Để kiểm nghiệm dễ dàng những vấn đề này thì bạn cần nhúng một IE trực quan vào ứng dụng của bạn thay vì dùng một IE chạy ngầm. Sau khi kiểm nghiệm xong thì bạn có thể chuyển dùng đối tượng IE trực quan về lại IE ngầm.

Tôi không cài MS Office nên không thực nghiệm được những vấn đề này.
 
Upvote 0
@phanminhphuonghl

Chỗ nào không nhập thành công là do Javascript chưa load option thì lệnh nhập đã thực thi.

Chèn đợi 1 giây hoặc vài giây nếu bắt buộc:
Application.Wait VBA.Now + 1/24/60/60

Hoặc dùng vòng lặp While trong khi element chưa load
JavaScript:
Dim timeout as Date
timeout  = vba.now + 3/24/60/60
Do while ie.document.getElementsByname("fields[districtId]")(0).getElementsByTagname("option").length > 1
    if vba.now > timeout then Exit do
Loop

timeout  = vba.now + 3/24/60/60
Do while ie.document.getElementsByname("fields[wardId]")(0).getElementsByTagname("option").length > 1
    if vba.now > timeout then Exit do
Loop
 
Upvote 0
@phanminhphuonghl

Chỗ nào không nhập thành công là do Javascript chưa load option thì lệnh nhập đã thực thi.

Chèn đợi 1 giây hoặc vài giây nếu bắt buộc:
Application.Wait VBA.Now + 1/24/60/60

Hoặc dùng vòng lặp While trong khi element chưa load
JavaScript:
Dim timeout as Date
timeout  = vba.now + 3/24/60/60
Do while ie.document.getElementsByname("fields[districtId]")(0).getElementsByTagname("option").length > 1
    if vba.now > timeout then Exit do
Loop

timeout  = vba.now + 3/24/60/60
Do while ie.document.getElementsByname("fields[wardId]")(0).getElementsByTagname("option").length > 1
    if vba.now > timeout then Exit do
Loop
Cám ơn bạn. Mình đã tham khảo được cách xử lý như sau, các bạn vui lòng chỉ dẫn thêm (code đang quan tâm kết quả nên chưa rút gọn):
Mã:
Sub VbaWeb()
  Dim oIE As Object            'InternetExplorer.Application
  Dim btnInput As Object   'MSHTML.HTMLInputElement
  Dim ieDoc As Object        'MSHTML.HTMLDocument
  Dim changeEvent As Object
  Dim sURL As String
'On Error Resume Next

Set oIE = CreateObject("InternetExplorer.Application")
    sURL = "https://tokhaiyte.vn"
With oIE
    .Navigate sURL
    .Visible = True
    Do While .Busy Or .ReadyState <> 4: DoEvents: Loop                              'Loop until the page finishes loading
End With

Set ieDoc = oIE.Document
Set changeEvent = ieDoc.createEvent("HTMLEvents")
    changeEvent.initEvent "change", True, False

'cac doan code khac

ieDoc.getElementsByname("fields[provinceId]")(0).Value = "5657e3ab7f8b9a117c8b4575"
ieDoc.getElementsByname("fields[provinceId]")(0).dispatchEvent changeEvent
Application.Wait Now + TimeValue("0:00:02")

ieDoc.getElementsByname("fields[districtId]")(0).Value = "5657e3ac7f8b9a117c8b4898"
ieDoc.getElementsByname("fields[districtId]")(0).dispatchEvent changeEvent
Application.Wait Now + TimeValue("0:00:02")

ieDoc.getElementsByname("fields[wardId]")(0).Value = "5657e3bd7f8b9a117c8b63f1"

Set oIE = Nothing
  Set ieDoc = Nothing
  Set btnInput = Nothing
  Set changeEvent = Nothing

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

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

Back
Top Bottom