Điều khiển IE bằng VBA

vbano1

SMod
Thành viên BQT
Điều khiển Internet Explorer bằng VBA là một chủ đề khá mới mẻ tại Việt Nam. Trong khuôn khổ bài viết này mình sẽ giới thiệu các bước để làm quen với việc Control IE by VBA.
Trước khi bước vào bài học, yêu cầu máy tính bạn cần cài đặt IE11 trở lên. Trình duyệt IE cũ hơn có thể không hoạt động được.

1. Yêu cầu:
Trên excel các bạn cần thiết định thư viện:
Microsoft HTML Object Library
Microsoft Internet Controls
Thông qua các bước sau:
  • ① Mở màn hình soạn thảo code VBA(VBE): Các bạn có thể sử dụng tổ hợp phím ALT+F11 để mở.
  • ②Menu => Tools => References
  • ③ Tích chọn「Microsoft HTML Object Library」và「Microsoft Internet Controls」
  • ④ Click OK.
Bạn cần đăng nhập để thấy đính kèm


Mã:
Sub IE()

 Dim objIE  As InternetExplorer

 'Tao doi tuong IE(InternetExplorer)
 Set objIE = CreateObject("InternetExplorer.Application")

 'Khoi dong IE(InternetExplorer)
 objIE.Visible = True 'Neu de la False thi IE van duoc khoi dong nhung ban se khong nhin thay trinh duyet dang duoc open.

End Sub
Hàm CreateObject với tư cách là đối tượng từ ứng dụng bên ngoài mà chúng ta muốn thao tác, ở đây là trình duyệt IE, cho nên không thể thiếu thao tác tạo đối tượng Object IE khi bắt đầu chương trình.
Việc sử dụng hàm CreateObject cũng có điểm chú ý, sau đây tôi sẽ thuyết minh cho các bạn.

Set Tên Object = CreateObject("Tên ứng dụng . Tên class")
Cấu trúc: CreateObject(class,[servername])
Tham số Class: Không thể giản lược. Bắt buộc phải khai báo.
Đối với tham số class, khi tạo đối tượng object sẽ chỉ định tên theo cú pháp như sau app_name.object_type
app_name
: Chỉ định rõ tên ứng dụng cung cấp đối tượng (object) cho chúng ta làm việc
object_type: Chỉ định rõ chủng loại class của object

Ví dụ:
InternetExplorer.Application・・・Ta làm việc với ứng dụng Internet Explorer
Excel.Application・・・Excel
Word.Application・・・Word
Access.Application・・・Access
PowerPoint.Application・・・PowerPoint

Tham số severname: Có thể giản lược.
Trong trường hợp sử dụng nội bộ trong máy tính của chúng ta thì chỉ định để trống, viết như sau (""). Trong trường hợp sử dụng từ mạng network bên ngoài, thì phải chỉ rõ tên sever. (Tạm thời các bạn không cần quan tâm tới thông số severname cũng được vì ứng dụng IE đã có trên máy tính của chúng ta rồi).

Một số ứng dụng chúng ta hay dùng khi code VBA.

Bạn cần đăng nhập để thấy đính kèm


Mã:
Sub sample()

 Dim objIE As InternetExplorer 'Kieu doi tuong la InternetExplorer

 'Tao doi tuong IE(InternetExplorer)
 Set objIE = CreateObject("InternetExplorer.Application")

  'Hien thi trinh duyet IE(InternetExplorer)
  objIE.Visible = True

  'Truy cap vao dia chi
  objIE.Navigate "https://tuhocvba.net/"

 'Menh lenh cho toi khi trang web duoc mo hoan toan
 Do While objIE.Busy = True Or objIE.ReadyState <> 4
  DoEvents
 Loop
   'De mo mot trang web con phu thuoc vao toc do truy cap mang, vi vay lenh tren co nghia la chờ cho tới khi web được load hoàn toàn.
End Sub
Kết quả:
Bạn cần đăng nhập để thấy đính kèm


Nguồn:
 

vbano1

SMod
Thành viên BQT
2. Làm quen với các thuộc tính, phương thức và các hàm quen thuộc hay dùng.
Các thông tin cần biết (dù có thứ không dùng tới nhưng nên đọc qua một lần)
Hàm DoEvents là hàm để điều khiển vào giữa tiến trình đang xử lý. Trong trường hợp xử lý bị mất nhiều thời gian (chả hạn như load trình duyệt web IE) hoặc thể hiện phần trăm công việc hoàn thành progressbar chúng ta cần update % liên tục cho label, tiến trình xử lý này chưa xong mà macro đã chạy sang đoạn code khác thì sẽ tạo ra rắc rối. Hàm DoEvents sẽ can thiệp để chờ cho quá trình này xử lý xong thì mới sang các câu lệnh khác trên VBA. Khi sử dụng nó thì chương trình sẽ chạy chậm hơn bình thường. Đối với điều khiển IE, nhất định chúng ta phải sử dụng nó để đảm bảo trình duyệt IE được mở ra.
Tham khảo: Xem video này và hãy thử bỏ DoEvents đi xem còn hiển thị tiến trình công việc trên progressbar không nhé.
Mã:
https://www.youtube.com/watch?v=VsXTvXs-HSo&list=PLCeKJ_XakmdmO0TXErVG3oyQT66lXPOnA&index=15
Hàm Now sẽ cho biết thời gian hiện tại gồm giờ phút giây, ngày tháng năm.
Mình chưa phải dùng hàm này trong code thực tế điều khiển IE.
Mã:
Sub sample()
MsgBox Now()
End Sub
Kết quả:
Bạn cần đăng nhập để thấy đính kèm


Hàm sleep sẽ dừng chương trình VBA trong khoảng thời gian mà bạn chỉ định. Điều này rất hữu ích khi xử lý IE. Ví dụ bạn cần cho web load, tính toán thời gian cần thiết là khoảng 3s thì bạn cho sleep 3s rồi mới sang các câu lệnh tiếp theo để chắc chắn rằng web đã load thành công. Thực tế cho thấy thỉnh thoảng do tốc độ mạng nên load web có lúc bị lỗi. Vì vậy để đảm bảo không có lỗi thì chúng ta vẫn sử dụng thêm hàm Sleep. Tùy thuộc vào mạng của bạn, mà trong code sẽ tinh chỉnh thông số sleep là 1s hay nhiều giây. Trong tool dịch phụ đề phim tự động, mình có dùng hàm sleep và cho chờ trong 3s để đảm bảo chắc chắn 100% trang web google translate load xong và không lỗi. Quá trình điều khiển IE có khi không được lợi về thời gian so với làm bằng tay, nhưng thao tác lặp đi lặp lại hàng ngàn lần thì máy móc làm vẫn hơn con người.
Mã:
Sub sample()
Sleep 3000
MsgBox "Cho 3s xu ly se dung chuong trinh"
End Sub
Ví dụ nếu muốn code sau 5 phút thì máy tính tắt, lúc đó chúng ta sẽ dùng hàm Sleep, hữu ích ghê.

Hàm TimeSerial chỉ định giờ phút giây, mình cũng chưa dùng hàm này vào việc gì trong thực tế.
Mã:
Dim Time As Variant
Time = TimeSerial(0, 56, 0)
Phương thức Navigate chỉ định URL cho IE. Tức là bạn muốn mở trang web nào thì truyền tham số link trang web đó cho nó.
Nó có 5 thông số nhưng mình cũng chưa tìm hiểu sâu. Các bạn cứ dùng nó như ví dụ ở bài viết đầu là được rồi.
Navigate(URL As String, [flags], [TargetFrameName], [PostData], [Headers])
Tham số URL bắt buộc phải có, không thể giản lược được.
Các tham số khác đều có thể giản lược. Điều khiển mở tab mới hay cửa sổ mới thì lưu ý tham số flags. (Mình chưa thử)

Thuộc tính Visible: Như đã nói, bạn muốn chạy ngầm thì cho là False, muốn hiển thị trình duyệt được bật lên giống thao tác bằng tay, quan sát được thì để là True. Mình thường để là True. Làm việc với IE mà. Cứ nhìn bằng mắt cho chắc. Kẻo ngồi đợi dài cổ mà hóa ra chương trình tẻo mà lại còn để code chạy ngầm thì khó biết.

Thuộc tính Busy: Web đang load dữ liệu hay là xử lý xong rồi, nếu là True thì đang load, nếu là False thì load xong rồi.
Thực tế quá trình xử lý web, thuộc tính này- nó sẽ biến đổi xoay vòng như này. True→False→True→False.
Ví dụ: Website xử dụng frame hoặc iframe (Cần có kiến thức về html và javascript tí). Nói ngắn gọn là bên trong trang web A lại có một cái khung load thông tin từ trang web B khác hiển thị thời tiết chả hạn. Như thế load web A thì ok rồi, mà bên trong nó lại còn load tiếp ông web B trong cái khung frame này. Thế thì lúc đầu là False là kết thúc rồi, nhưng sau đó do lại load tiếp thì thuộc tính này lại chuyển thành True.

Thuộc tính ReadyState: Hiển thị trạng thái đọc dữ liệu web, tức là load web ấy. Nó có 5 mức từ 0 đến 4.
Trạng thái objIE.readyState=4 tức là toàn bộ trang web được load hoàn toàn rồi nhé.
Mã:
objIE.readyState = 0~4
Mình chỉ quan tâm tới trạng thái web được load hoàn toàn, do đó không cần tìm hiểu kỹ thêm.
Bây giờ chúng ta đã hiểu tại sao trong chương trình ví dụ ở bài viết số 1, chúng ta viết:
Mã:
'Menh lenh cho toi khi trang web duoc mo hoan toan
 Do While objIE.Busy = True Or objIE.ReadyState <> 4
'Trong khi web chưa load xong dữ liệu thì còn phải làm việc load cho tới khi nào xong
  DoEvents
 Loop
Phương thức Refresh: Mình chưa phải sử dụng tới nó trong code thực tế. Nó giống như bạn refresh trang web bằng tay ấn F5 ấy.
Mã:
objIE.Refresh
Ngoài ra các thuộc tính của IE rất đáng để tham khảo.
Bạn tham khảo thêm ở đây:
Bản thân mình hay dùng các thuộc tính sau:
Mã:
objIE.AddressBar = False '=true thi hien thi thanh nhập URL. Thực tế không cần thiết.
'Dat vi tri IE tren man hinh. Thực tế hay sử dụng, xem như nào thì tiện cho bản thân.
'ví dụ với tool dịch phụ đề phim, mình muốn xem tool chạy và xem bản dịch để học ngoại ngữ luôn
'cho nên mình căn chỉnh để nó ra giữa màn hình sao cho dễ nhìn.
objIE.Top = 10
objIE.Left = 10
objIE.Width = 200 'Chieu rong cua so IE duoc mo ra
objIE.Height = 200 'Chieu cao cua so IE duoc mo ra
Bạn cần đăng nhập để thấy hình ảnh


Nguồn tham khảo cho toàn bộ bài viết:
 

vbano1

SMod
Thành viên BQT
3. Bàn về sự kiện load web xong hay chưa.
Trong các đoạn code đã nói ở các bài viết trên, sẽ có người lo lắng rằng để hàm DoEvents trong vòng lặp Loop như trên có đáng ngại không. Nếu vòng lặp Loop trên là vô hạn thì làm thế nào?
Thực tế là trang web nào cũng tới lúc kết thúc (tức là chúng ta chờ cho tới khi truy cập được), chứ làm gì có trang web nào truy cập hàng giờ mà vẫn chưa xong. Vì vậy vòng lặp Loop trên không phải là vô hạn, cho nên không đáng lo.
Tuy nhiên trong bài viết này, chúng ta sẽ bàn bạc để xử lý vấn đề này triệt để hơn.
Ở bài viết trước, chúng ta đã quen với các hàm và thuộc tính, bây giờ chúng ta đã có đủ công cụ để làm việc rồi. Nào, hãy bắt tay vào với đoạn code ở dưới và lý giải nó.
Mã:
Dim timeOut  as Date
timeOut = Now + TimeSerial(0, 0, 20)

Do While objIE.Busy = True Or objIE.readyState <> 4
  DoEvents
  Sleep 1 'VBA se tam dung trong 1s, để đảm bảo IE đã hoạt động
  If Now > timeOut Then
    'Sau khoang thoi gian 20s ma van chua load duoc web thi refresh web
    objIE.Refresh
    timeOut = Now + TimeSerial(0, 0, 20) 'Thiet dinh lai thoi gian refresh web
  End If
Loop

'Thoi diem hien tai + 20s, thoi gian refresh web
timeOut = Now + TimeSerial(0, 0, 20)

Do While objIE.document.readyState <> "complete"
  DoEvents
  Sleep 1
  If Now > timeOut Then
    'Sau khoang thoi gian 20s ma van chua load duoc web thi refresh web
    objIE.Refresh
    timeOut = Now + TimeSerial(0, 0, 20)
  End If
Loop
Ý tưởng của đoạn code trên là:
Bạn cần đăng nhập để thấy hình ảnh

Nếu mà trang web vẫn chưa được load thì cứ chạy DoEvents để đòi truy cập, đồng thời 20s Refresh lại một lần.
Ở đoạn code trên chú ý: objIE.document.readyState objIE.readyState, chúng có giá trị trả về khác nhau. Nếu trang web đã được load dữ liệu xong xuôi thì giá trị trả về của objIE.readyState =4, còn objIE.document.readyState = "complete". Đây là điểm khác nhau duy nhất, còn về bản chất thì chúng giống nhau. objIE.document.readyState = "complete" tức là trạng thái HTML Document của trang web đã load xong xuôi, có thể đọc dữ liệu cũng như thao tác trên web. (Chú ý web có nhiều trạng thái, chả hạn load dữ liệu thì ok nhưng bạn không thể click trên web, nó tương tự như trạng thái trang web bị đơ ấy. Tóm lại ở trạng thái "complete" thì tức là nó đã load bình thường rồi).
Bây giờ tôi sẽ dùng đoạn code trên để chèn vào chương trình trong bài viết đầu tiên mà tôi đã giới thiệu cho các bạn:
Mã:
Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal ms As LongPtr) 'De su dung duoc ham sleep, chung ta nhat dinh phai khai bao kernel32
Sub sample2()


  Dim objIE As InternetExplorer
  Dim timeOut As Date       'tuhocvba them vao bien moi cho vi du sample2

  'Tao doi tuong IE(InternetExplorer)

  Set objIE = CreateObject("InternetExplorer.Application")


  'Hien thi trinh duyet IE(InternetExplorer)

  objIE.Visible = True


  'Truy cap vao dia chi

  objIE.navigate "https://tuhocvba.net/"
'tuhocVBA vo hieu hoa doan code o duoi

  'Menh lenh cho toi khi trang web duoc mo hoan toan

'  Do While objIE.Busy = True Or objIE.readyState <> 4
'
'    DoEvents
'
'  Loop
'
'Thay vao do, chung ta su dung doan code duoi day de chac chan rang trang web duoc load


'Thoi diem hien tai + 20s, thoi gian refresh web neu toi luc ay ma chua load xong
timeOut = Now + TimeSerial(0, 0, 20)

Do While objIE.Busy = True Or objIE.readyState <> 4
  DoEvents
  Sleep 1
  If Now > timeOut Then
    'Sau khoang thoi gian 20s ma van chua load duoc web thi refresh web
    objIE.Refresh
    timeOut = Now + TimeSerial(0, 0, 20) 'Thiet dinh lai thoi gian refresh web
  End If
Loop

'Thoi diem hien tai + 20s, thoi gian refresh web
timeOut = Now + TimeSerial(0, 0, 20)

Do While objIE.document.readyState <> "complete"
  DoEvents
  Sleep 1
  If Now > timeOut Then
    'Sau khoang thoi gian 20s ma van chua load duoc web thi refresh web
    objIE.Refresh
    timeOut = Now + TimeSerial(0, 0, 20)
  End If
Loop

End Sub
Như vậy chương trình lần này có vẻ ổn hơn chương trình ban đầu rồi đó, chúng ta đã tính toán web chưa load được thì cứ mỗi 20s ta lại refresh một lần. Ngoài ra để tránh chương trình VBA chạy quá nhanh trong khi IE thì vẫn đang ì ạch load web, ta còn sử dụng hàm Sleep để cho VBA đứng đợi IE trong 1s. Hai vòng lặp Do Loop ở trên có giá trị tương đương, vì mấy thuộc tính có ý nghĩa cứ na ná nhau, nên ta sử dụng hết cả hai vòng lặp trong cùng một chương trình. Mỗi vòng lặp đối ứng một thuộc tính khác nhau ( objIE.Busy = True Or objIE.readyState <> 4 và objIE.document.readyState <> "complete" ). Mục đích của việc này không gì khác chính là chúng ta mong muốn trang web được load hoàn toàn.

Tất nhiên lựa chọn Refresh không phải là lựa chọn duy nhất, chúng ta có một lựa chọn khác, đó là thoát vòng lặp nếu như trong 20s mà không load xong trang web mà chúng ta cần, bằng cách sử dụng lệnh Goto.
Mã:
timeOut = Now + TimeSerial(0, 0, 20)

Do While objIE.Busy = True Or objIE.readyState <> 4
  DoEvents
  Sleep 1
  If Now > timeOut Then
    'Sau khoang thoi gian 20s ma van chua load duoc web thi refresh web
    GoTo label1
    timeOut = Now + TimeSerial(0, 0, 20) 'Thiet dinh lai thoi gian refresh web
  End If
Loop

label1:
'Thoi diem hien tai + 20s, thoi gian refresh web
timeOut = Now + TimeSerial(0, 0, 20)

Do While objIE.document.readyState <> "complete"
  DoEvents
  Sleep 1
  If Now > timeOut Then
    'Sau khoang thoi gian 20s ma van chua load duoc web thi refresh web
    GoTo Label2
    timeOut = Now + TimeSerial(0, 0, 20)
  End If
Loop
Label2:
Về lệnh GoTo nếu ai chưa rành thì có thể tham khảo .

Để kết thúc bài viết này, chúng ta đi tới một chương trình tham khảo mà tôi sẽ sử dụng nó cho toàn bộ các chương trình về sau khi cân truy cập web.
Về việc cứ 20s refresh một lần, các bạn có thể chỉnh lại là 3s hay 4s tùy thuộc vào tốc độ web của các bạn. Lẽ dĩ nhiên khi code điều khiển IE, chúng ta sẽ phải thử truy cập bằng tay vô trang web mà chúng ta muốn, để xem tốc độ truy cập như nào rồi từ đó mới tiến hành code.
Mã:
Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal ms As LongPtr) 'De su dung duoc ham sleep, chung ta nhat dinh phai khai bao kernel32
Sub truycapweb()

  Dim objIE  As InternetExplorer
  Dim timeOut As Date

  'Tao object IE
  Set objIE = CreateObject("InternetExplorer.Application")


  'Hien thi trinh duyet IE
  objIE.Visible = True

  'Truy cap dia chi web
  objIE.navigate "https://tuhocvba.net/"

  'Chung ta mong muon trang web duoc load hoan toan trong 20s. Cac ban co the chinh lai thong so nay
  timeOut = Now + TimeSerial(0, 0, 20)

  Do While objIE.Busy = True Or objIE.readyState <> 4
    DoEvents
    Sleep 1
    If Now > timeOut Then
      objIE.Refresh
      timeOut = Now + TimeSerial(0, 0, 20)
    End If
  Loop
  'Chung ta mong muon trang web duoc load hoan toan trong 20s. Cac ban co the chinh lai thong so nay
  timeOut = Now + TimeSerial(0, 0, 20)

  Do While objIE.document.readyState <> "complete"
    DoEvents
    Sleep 1
    If Now > timeOut Then
      objIE.Refresh
      timeOut = Now + TimeSerial(0, 0, 20)
    End If
   Loop

End Sub
Nguồn tham khảo:
 

Euler

Mod
Thành viên BQT
Như vậy là việc truy cập một website đã được giải quyết xong. Bây giờ muốn thao tác với website thì phải hiểu một chút về mã html.
Mã html là gì?
html là ngôn ngữ siêu văn bản. Bạn có thể tìm hiểu ở đây, rất chi tiết:
Mã:
https://www.w3schools.com/html/
Để hình dung nó là gì, bạn mở một trang web bất kỳ và click chuột phải chọn view source.
Bạn cần đăng nhập để thấy hình ảnh


Bạn cần đăng nhập để thấy hình ảnh


Tóm lại một thẻ html sẽ ở dưới dạng như sau:
Bạn cần đăng nhập để thấy hình ảnh

Ta ví dụ:
Mã:
<title>tuhocvba.net</title>
Bây giờ bạn mở Notepad lên và dán đoạn code dưới đây vào:
Mã:
<html>

 <head>

  <title>tuhocvba.net</title>

 </head>

 <body>

 <h1>Trang web tu hoc vba</h1>

  <p>Ban co the dung VBA de dieu khien IE va lay duoc thong tin o day</p>

  <p id="text">Rat la tien loi, hay thu dung xem nhe</p>

  <a href="http://www.tuhocvba.net/">Website tu hoc vba co moi truong thao luan tot nhat Viet Nam</a>

 </body>

</html>
Lưu file lại với tên tuhocvba.html
Bạn cần đăng nhập để thấy hình ảnh

Sản phẩm html của chúng ta như thế này:
Bạn cần đăng nhập để thấy hình ảnh

Chúng ta double click để mở file và được như thế này:
Bạn cần đăng nhập để thấy hình ảnh
 
T

thanhphuongvip

Guest
Có code nào có thể áp dụng trên các trình duyệt khác đc ko, ví dụ như Chrome, FireFox. Vì thực tế trình duyệt IE hầu như ko ai sài vì những hạn chế của nó.
 

vbano1

SMod
Thành viên BQT
Có code nào có thể áp dụng trên các trình duyệt khác đc ko, ví dụ như Chrome, FireFox. Vì thực tế trình duyệt IE hầu như ko ai sài vì những hạn chế của nó.
Mục đích điều khiển IE là để tự động hóa một việc nào đó, hoặc lấy dữ liệu từ web. Do đó nó chẳng liên quan gì tới thẩm mỹ cũng như sở thích. Vì vậy nó cũng không liên quan tới sở thích của bạn là thích dùng trình duyệt này hơn trình duyệt kia. Chúng ta chỉ dùng nó để lấy dữ liệu, ngoài ra không quan tâm tới gì khác. Về câu hỏi của bạn: Trong khả năng hiểu biết của mình, thì mình không biết VBA có thể điều khiển được Chrome hay Firefox hay không.

Trở lại vấn đề, hôm nay chúng ta có bài toán như sau:
Tôi muốn tạo từ điển kanji(chữ hán). Và tôi có trang web sau.
Hãy truy cập link sau:
Mã:
https://kanji.jitenon.jp/kanjil/5741.html
Tôi muốn lấy thông tin của chữ hán trong khung màu đỏ, và cho vào excel:
Bạn cần đăng nhập để thấy hình ảnh

Tất nhiên tôi không muốn làm bằng tay.
 

Euler

Mod
Thành viên BQT
Làm rõ nhiệm vụ: Giả thiết tôi cần lấy các thông tin ở những nơi được khoanh đỏ.
Bạn cần đăng nhập để thấy hình ảnh


Tôi thực hiện view source để xem thông tin cần lấy nằm ở đâu:
Bạn cần đăng nhập để thấy hình ảnh


Như vậy thông tin nằm trong thẻ có class = kanjirighttb .
Tôi sẽ dùng phương thức GetElementsByClassName để lấy thông tin trong class này.
Mã:
Sub test()
    Call takekanjithongtin("https://kanji.jitenon.jp/kanjil/5741.html")
End Sub
Sub takekanjithongtin(lk As String)
' lay thong tin mot chu
    Dim HTMLDoc     As HTMLDocument 'Lấy mã html trong trang web được mở
    Dim oBrowser As InternetExplorer 'trang web
   
    Dim oHTML_Element   As IHTMLElement
    Dim s               As String
    Set oBrowser = New InternetExplorer
    oBrowser.Silent = True
    Application.Wait (Now + TimeValue("0:00:1")) 'chờ cho IE hoạt động
    oBrowser.navigate lk 'Mở trang web có link là lk
    oBrowser.Visible = True
    Application.Wait (Now + TimeValue("0:00:1")) 'chờ cho IE hoạt động
    Do
    ' Wait until the Browser is loaded
    Loop Until oBrowser.readyState = READYSTATE_COMPLETE
    Set HTMLDoc = oBrowser.document 'lấy toàn bộ mã html có trong trang web đang được mở
    Application.Wait (Now + TimeValue("0:00:2"))
   
    For Each oHTML_Element In HTMLDoc.GetElementsByClassName("kanjirighttb")
        s = oHTML_Element.innerHTML 'lấy phần text nằm trong thẻ class = kanjirighttb
        Exit For
    Next
    Msgbox s
End sub
Tôi sẽ thu được s như sau:
Bạn cần đăng nhập để thấy hình ảnh


Đến bây giờ chỉ còn công đoạn tách các phần cần lấy trong đoạn text trên là được.
Tôi còn phần 漢字構成
Tôi ấn ctr+F và tìm được:
Bạn cần đăng nhập để thấy hình ảnh

Các ký tự tìm thấy có gì đó khiến tôi băn khoăn, tôi copy từ dòng 196 cho tới 212 cho vào file text, lưu với tên xemxet.html và được:
Bạn cần đăng nhập để thấy hình ảnh


Không còn nghi ngờ gì nữa, đây chính là những ký tự tôi cần lấy.
Bằng cách tương tự tôi cũng lấy được đoạn text này:
Mã:
kose =""
For Each oHTML_Element In HTMLDoc.GetElementsByClassName("kanjikouseilist")
        s = oHTML_Element.innerText
        kose = kose & s & ";"
Next
Chú ý thiết định trên excel để chạy được code: HTML ObjectInternet Controls.
Bạn cần đăng nhập để thấy hình ảnh
 

thanhphong

Thành viên
Kiến thức trong topic này đã được chúng tôi vận dụng để lấy thông tin chứng khoán từ website, các bạn có thể .
 

tuhocvba

Administrator
Thành viên BQT
4. Thao tác với HTML element bằng Excel VBA
Kiến thức thao tác với IE bằng VBA khá nhiều, để dịch hết sẽ mất nhiều thời gian, do đó chúng tôi sẽ lựa chọn các phần kiến thức được dùng phổ biến hơn cả. Phần này là một phần quan trọng, các bạn muốn lấy thông tin từ website, thì cần phải đọc kỹ phần này.

4.1 Về DOM(Document Object Model):
DOM là từ viết tắt giản lược của Document Object Model. Đó là các thành phần cấu tạo nên cấu trúc một file html : html,head,body,p ...
Nếu có một chút kiến thức về HTML thì phần này sẽ dễ dàng hơn. Mình giới thiệu qua về cấu trúc HTML nhé:
Nó gồm các element như dưới đây:
Bạn cần đăng nhập để thấy đính kèm

HTML là HyperText Markup Language, là một ngôn ngữ để tạo trang web. Dù cho bạn sử dụng các ngôn ngữ như PHP, ASP,... thì HTML vẫn là kiến thức cơ bản nhất để tạo một trang web.
Ví dụ: Bạn hãy copy đoạn text sau cho vào NotePad và lưu lại với file name là : tuhocvba.html
Mã:
<html>

 <head>

  <title>tuhocvba.net</title>

 </head>

 <body>

  <p>Day la noi dung cua the p</p>
  <a href="★Link URL★">Phan chu hien thi de nguoi dung click vao</a>

 </body>

</html>
Sự khác nhau giữa tag và element:
Trong ngôn ngữ HTML, chúng ta có khái niệm thẻ tag. Nó có cấu trúc như sau:
Bạn cần đăng nhập để thấy đính kèm

Thẻ tag là thẻ mà bạn có thể nhận thấy là chúng sử dụng các dấu < và > để bao quanh tên thẻ như hình ảnh trên.
Element là toàn bộ phần thẻ tag và nội dung giữa bắt đầu thẻ và kết thúc thẻ.
Giả sử ta có trang web có mã html như sau:
Mã:
<html>

 <head>

  <title>tuhocvba.net</title>

 </head>

 <body>

 <h1>VBA Viet Nam</h1>

  <p>Chung ta se cung nhau thi nghiem lay noi dung cua mot the trong html nhe</p>

  <p id="text">Nhat dinh hay thu lam mot lan cung chung toi</p>

  <a href="https://tuhocvba.net/">Website tuhocvba.net</a>

 </body>

</html>
Thực chiến: Lấy nội dung thẻ title
1. Chúng ta sẽ lấy toàn bộ nội dung HTML
2. Trong đó chúng ta tách ra chỉ lấy nội dung của thẻ title
Mã:
objIE.document.title
Ngoài ra người ta cũng có thể dùng
Mã:
objIE.LocationName
Trong thực tế hiếm khi chúng ta cần lấy nội dung title của một trang web, do đó tôi lược dịch phần này.

Thực chiến: Lấy nội dung của thẻ p đầu tiên.
Trong ví dụ mã HTML ở trên, ta thấy thẻ p được dùng hai lần. Điều này thường xảy ra trong thực tế, một thẻ có thể xuất hiện nhiều lần. Tuy nhiên, nếu chỉ muốn lấy nội dung thẻ p xuất hiện đầu tiên thì cần phải làm thế nào?
1. Chúng ta lấy toàn bộ nội dung HTML.
2. Chúng ta lấy toàn bộ nội dung ở những nơi có thẻ p.
3. Chúng ta lấy nội dung của thẻ p xuất hiện đầu tiên.
4. Chúng ta lấy toàn bộ element của thẻ p đầu tiên này.
Mã:
objIE.document.getElementsByTagName("p")(0).outerHTML
Thực chiến: Lấy theo id.
id thường là các chỉ số nhận dạng, có tính duy nhất. Trong thực tế, lấy theo id là dễ nhất. Trong ví dụ HTML ở trên ta sẽ lấy nội dung thẻ p có id là "text". (thẻ p thứ 2).
1. Lấy toàn bộ nội dung HTML.
2. Lấy nội dung nơi có thẻ id = "text"
3. Lấy nội dung bên trong (nội dung element) của thẻ có id nói trên.
Mã:
objIE.document.getElementById("text").innerText

Thực chiến: Click vào đường link có trên trang web

1. Lấy toàn bộ nội dung HTML
2. Trong đó ta lấy nội dung nơi có thẻ là a.
3. Thẻ là a là nội dung bên trong chứa chữ "tuhocvba.net" thì làm:
4. Click vào thẻ
Mã:
  For Each objtag In objIE.document.getElementsByTagName("a")
                                                            
    If InStr(objtag.outerHTML, "tuhocvba.net") > 0 Then

      objtag.Click

      Exit For

    End If

  Next
Nguồn tham khảo:
 

Euler

Mod
Thành viên BQT
4.2 Lấy toàn bộ element có trong HTML Document
  • ①Khai báo biến số
  • ②Sử dụng code mẫu, thủ tục ieView, chỉ định cho nó đường link website URL , nó sẽ khởi động IE mở trang web đó ra.
  • ③Lấy toàn bộ Object của HTML Document
  • ④Lấy toàn bộ element có trong HTML Document cất trong collection
  • ⑤Trong Collection, ta lấy element mà ta chỉ định
  • ⑥Lấyy HTML code bao gồm cả thẻ tag của element mà ta chỉ định lấy
  • ⑦Thông qua Msgbox, ta cho hiển thị toàn bộ element có trong HTML Document
ieView là gì?
Đây là thủ tục do chúng ta xây dựng, để khởi động một trang web bất kỳ, đường link URL của trang web sẽ do chúng ta chỉ định
Mã:
Sub ieView(objIE As InternetExplorer, _
           urlName As String, _
           Optional viewFlg As Boolean = True, _
           Optional ieTop As Integer = 0, _
           Optional ieLeft As Integer = 0, _
           Optional ieWidth As Integer = 600, _
           Optional ieHeight As Integer = 800)
    
  'Tao Object IE(InternetExplorer)
    Set objIE = CreateObject("InternetExplorer.Application")
    
    With objIE
        
    'Hien thi hay khong hien thi IE(InternetExplorer)
        .Visible = viewFlg
        
        .Top = ieTop 'Vi tri Y
        .Left = ieLeft 'Vi tri X
        .Width = ieWidth 'Chieu ngang cua trinh duyet
        .Height = ieHeight 'Chieu cao cua trinh duyet
        
    'Duong link trang web chung ta muon truy cap
        .navigate urlName
    
    End With
    
  'Kiem tra IE(InternetExplorer) da duoc open thanh cong hay chua
    Call ieCheck(objIE)
    
End Sub
Cấu trúc: ieView(objIE,urlName,[viewFlg],[ieTop],[ieLeft],[ieWidth],[ieHeight])
Tên tham sốKiểu dữ liệuNội dung giải thíchGiá trị ví dụGiá trị khởi tạo ban đầuCó thể giản lược hay không?
'// x: Không thể giản lược
objIEInternetExplorerChỉ định InternetExplorer ObjectobjIE,objIE2 ×
urlNameStringChỉ định đường link trang web cần mở ra" " ×
viewFlgBooleanKhi chỉ định là「True」,người dùng sẽ nhìn thấy trang web được mở ra; khi chỉ định là「False」, người dùng sẽ không thấy trang web được mở ra dù thực tế là nó đang được mở ra. Giá trị mặc định là True nếu bạn phớt lờ không chỉ định rõ ràng giá trị cho tham số này.True,False
TRUE​
ieTopIntegerChỉ định vị trí của trình duyệt sẽ được đặt ở đâu theo trục tọa độ Y.
100​
0​
ieLeftIntegerChỉ định vị trí của trình duyệt sẽ được đặt ở đâu theo trục tọa độ X.
150​
0​
ieWidthIntegerChỉ định bề rộng cho trình duyệt.
400​
600​
ieHeightIntegerChỉ định chiều cao cho trình duyệt
300​
800​

ieCheck là gì?
Đây là thủ tục do chúng ta tự xây dựng, nhằm kiểm tra xem trang web đã được mở ra thành công hay chưa?
Mã:
#If VBA7 Then
Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal ms As LongPtr)
#Else
Private Declare Sub Sleep Lib "kernel32" (ByVal ms As Long)
#End If

Sub ieCheck(objIE As InternetExplorer)

 Dim timeOut As Date

 'Thoi gian cho 20s de dam bao trang web duoc mo ra hoan toan.
 'Ban co the sua lai thoi gian 20s nay thanh con so khac phu hop voi toc do internet cua ban'
 timeOut = Now + TimeSerial(0, 0, 20)

 Do While objIE.Busy = True Or objIE.ReadyState <> 4
  DoEvents
  Sleep 1
  If Now > timeOut Then
   objIE.Refresh
   timeOut = Now + TimeSerial(0, 0, 20)
   End If
 Loop

 timeOut = Now + TimeSerial(0, 0, 20)

 Do While objIE.document.ReadyState <> "complete"
  DoEvents
  Sleep 1
  If Now > timeOut Then
   objIE.Refresh
   timeOut = Now + TimeSerial(0, 0, 20)
  End If
  Loop

End Sub
Tên tham sốKiểu dữ liệuNội dung giải thíchGiá trị ví dụGiá trị khởi tạo ban đầuCó thể giản lược hay không?
'// x: Không thể giản lược
objIEInternetExplorerChỉ định InternetExplorer ObjectobjIE,objIE2 ×

Document Property là gì?
Cấu trúc:
objIE.document.TenThuocTinh/TenPhuongThuc
Để nhớ tên các thuộc tính hay phương thức có lẽ là không cần thiết, sau đây thông qua các ví dụ, các bạn sẽ làm quen dần dần.

ALL Collection là gì?
All là toàn bộ các element có trong HTML document.
Cấu trúc:
objIE.document.All.TenThuocTinh/TenPhuongThuc
objIE.document.All(Element thứ bao nhiêu).TenThuocTinh/TenPhuongThuc

outerHTML Property là gì?
outerHTML là toàn bộ nội dung của element, bao gồm cả thẻ tag của element đó.

Ở trên tôi đã cho các bạn hai đoạn code, các bạn copy chúng cho vào Module1, Module2.
Còn đoạn code dưới đây các bạn cho vào Module 3:
Mã:
Sub sample()

  Dim objIE  As InternetExplorer

  'Trich xuat du lieu tu trang web
  Call ieView(objIE, "http://www.vba-ie.net/code/all.html")
 
  MsgBox objIE.document.all(0).outerHTML

End Sub
Kết quả chạy code được là:
Bạn cần đăng nhập để thấy hình ảnh


Thuyết minh-Giải thích:
Mã:
Sub sample()

  Dim objIE  As InternetExplorer
Chúng ta làm việc với đối tượng IE do đó chúng ta phải khai báo.

Tiếp theo, tôi giải thích dòng code sau, tôi nghĩ đây cũng là điều các bạn quan tâm nhất:
Mã:
MsgBox objIE.document.all(0).outerHTML
Là như thế này:
Mã:
【objIE.document.all(0).outerHTML】
objIE = InternetExplorer Object
document = HTML  Document
all = Là toàn bộ các element có trong Document
all(0) = Là phần tử đầu tiên trong collection all
outerHTML = Là nội dung HTML code của element all(0), bao gồm cả thẻ tag của nó.
Phần tử element đầu tiên là gì thì các bạn hãy xem nội dung HTML Document ở trên, thẻ tag đầu tiên là gì?
Đó chính là <html>~</html> . Do đó all(0) chính là element có thẻ tag này. Do đó all(0) thì ta sẽ lấy được toàn bộ nội dung của thẻ này, cũng là toàn bộ nội dung HTML Document của trang Web.
Mã:
all(0) = <html> ~ </html>
all(1) = <head> ~ </head>
all(2) = <meta ~ />
all(3) = <title> ~ </title>
all(4) = <body> ~ </body>
Nguồn tham khảo:
 

dkkx3a

Thành viên mới
Mình đang cố thực hành theo hướng dẫn bài này, mình có đoạn mã html như sau:
<p id="h.p_gw36Q6EjR1Wc" class="zfr3Q" style="text-align: center;">
<strong>Ver_20200602</strong>
</p>

Trong đó id kia là duy nhất, mình muốn lấy được thông tin chữ Ver_20200602 thì làm như thế nào ạ? Xin cảm ơn
 

tuhocvba

Administrator
Thành viên BQT
Dùng:
Mã:
objIE.document.getElementById("h.p_gw36Q6EjR1Wc ").innerText
Sẽ thu được s:
Mã:
<strong>Ver_20200602</strong>
Dùng InstrRev xác định ký tự < đầu tiên bên phải. Giả sử vị trí là n.
Dùng Mid(s,9, n-9) để tách lấy từ ký tự thứ 9 tới vị trí n-1 (độ dài chuỗi cần lấy là n-9).
 

vbano1

SMod
Thành viên BQT
4.3 Lấy số lượng element trong HTML Document
Nói tóm lại trong trang web mà bạn quan tâm có bao nhiêu thẻ tag đang được sử dụng, trong phần này chúng ta sẽ bàn về điều đó.
Mã:
cnt = objIE.document.All.Length
Nào, chúng ta hãy cùng nhau đi vào ví dụ cụ thể:
Mã:
#If VBA7 Then
Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal ms As LongPtr)
#Else
Private Declare Sub Sleep Lib "kernel32" (ByVal ms As Long)
#End If
Sub sample()

  Dim objIE  As InternetExplorer

  'Khoi dong IE va truy cap trang web sau:
  Call ieView(objIE, "https://tuhocvba.net/")
 
  MsgBox "so luong the tag la : " & objIE.document.all.Length

End Sub
Sub ieView(objIE As InternetExplorer, _
           urlName As String, _
           Optional viewFlg As Boolean = True, _
           Optional ieTop As Integer = 0, _
           Optional ieLeft As Integer = 0, _
           Optional ieWidth As Integer = 600, _
           Optional ieHeight As Integer = 800)
    
    'Tao object IE
    Set objIE = CreateObject("InternetExplorer.Application")
    
    With objIE
        
        'IE(InternetExplorer): Hien thi/Khong hien thi
        .Visible = viewFlg
        
        .Top = ieTop  'Vi tri truc Y
        .Left = ieLeft  'Vi tri truc X
        .Width = ieWidth  'Chieu rong
        .Height = ieHeight  'Chieu cao
        
        'Chi dinh duong link
        .navigate urlName
    
    End With
    
    'Kiem tra trang web da load xong chua
    Call ieCheck(objIE)
    
End Sub
Sub ieCheck(objIE As InternetExplorer)

  Dim timeOut As Date

  'Thoi gian cho de trang web hien thi hoan toan
  timeOut = Now + TimeSerial(0, 0, 20)

  Do While objIE.Busy = True Or objIE.readyState <> 4
    DoEvents
    Sleep 1
    If Now > timeOut Then
      objIE.Refresh
      timeOut = Now + TimeSerial(0, 0, 20)
    End If
  Loop

  timeOut = Now + TimeSerial(0, 0, 20)

  Do While objIE.document.readyState <> "complete"
    DoEvents
    Sleep 1
    If Now > timeOut Then
      objIE.Refresh
      timeOut = Now + TimeSerial(0, 0, 20)
    End If
   Loop

End Sub
Chạy thủ tục sample ở trên, chúng ta được kết quả, trang chủ của tuhocvba.net có 1238 thẻ tag.
Chú ý, để chạy được chương trình, bạn cần thiết định thư viện sau:
Microsoft HTML Object Library
Microsoft Internet Controls

Bạn cần đăng nhập để thấy đính kèm
 

Euler

Mod
Thành viên BQT
4.4 Lấy nội dung thẻ head và thẻ body
Chúng ta hãy xem lại cấu trúc html của một trang web, nó sẽ có dạng như sau:
Bạn cần đăng nhập để thấy hình ảnh

Bây giờ tôi sẽ thực thi lấy nội dung thẻ head và thẻ body:
Phần code chính là:
Mã:
objIE.document.head.outerHTML
objIE.document.body.outerHTML
Ta đi vào chương trình cụ thể:
Mã:
#If VBA7 Then
Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal ms As LongPtr)
#Else
Private Declare Sub Sleep Lib "kernel32" (ByVal ms As Long)
#End If
Sub sample()

  Dim objIE  As InternetExplorer

  'Khoi dong IE va truy cap website
  Call ieView(objIE, "https://tuhocvba.net/")
 
  'Lay noi dung the head
  MsgBox objIE.document.head.outerHTML
 
  'Lay noi dung the body
  MsgBox objIE.document.body.outerHTML

End Sub
Sub ieView(objIE As InternetExplorer, _
           urlName As String, _
           Optional viewFlg As Boolean = True, _
           Optional ieTop As Integer = 0, _
           Optional ieLeft As Integer = 0, _
           Optional ieWidth As Integer = 600, _
           Optional ieHeight As Integer = 800)
    
    'Tao object IE
    Set objIE = CreateObject("InternetExplorer.Application")
    
    With objIE
        
        'IE(InternetExplorer): Hien thi/Khong hien thi
        .Visible = viewFlg
        
        .Top = ieTop  'Vi tri truc Y
        .Left = ieLeft  'Vi tri truc X
        .Width = ieWidth  'Chieu rong
        .Height = ieHeight  'Chieu cao
        
        'Chi dinh duong link
        .navigate urlName
    
    End With
    
    'Kiem tra trang web da load xong chua
    Call ieCheck(objIE)
    
End Sub
Sub ieCheck(objIE As InternetExplorer)

  Dim timeOut As Date

  'Thoi gian cho de trang web hien thi hoan toan
  timeOut = Now + TimeSerial(0, 0, 20)

  Do While objIE.Busy = True Or objIE.readyState <> 4
    DoEvents
    Sleep 1
    If Now > timeOut Then
      objIE.Refresh
      timeOut = Now + TimeSerial(0, 0, 20)
    End If
  Loop

  timeOut = Now + TimeSerial(0, 0, 20)

  Do While objIE.document.readyState <> "complete"
    DoEvents
    Sleep 1
    If Now > timeOut Then
      objIE.Refresh
      timeOut = Now + TimeSerial(0, 0, 20)
    End If
   Loop

End Sub
Kết quả:
Bạn cần đăng nhập để thấy đính kèm


Và:
Bạn cần đăng nhập để thấy đính kèm
 

halongbay1987

Thành viên mới
Cám ơn bài viết bổ ích của bác vbano1, đây đúng là thứ e đang cần, có gì chưa hiểu nhờ bác giúp đỡ thêm, năm mới chúc bác thật nhiều sức khỏe và dành nhiều thời gian nghiên cứu xây dựng diễn đàn ngày một lớn mạnh
 

Nguyễn việt nam

Thành viên mới
Em chào anh chị.
E mới nghiên cứu về kết nối VBA với IE
Em có một đoạn code trong ie như sau:

<td>
<input name="ctl04$eDDocTypeNumber$eDDocTypeNumber" class="ms-long" id="ctl04_eDDocTypeNumber_eDDocTypeNumber" style="font-size: 14px;" type="text" edsearchkey="" autofill="true" limitone="True" checkinput="true" relativedatafield="eDDocType" edfieldtype="eDTextSuggest" selectedids="11" autocomplete="OFF">
</td>

E muốn điền thông tin vào 1 ô (ô này mỗi lần e nhập 1 loại văn bản ví dụ như chữ "công văn" thì e thấy tại chỗ selectedids ="11", nếu nhập chữ "quyết định" thì phần selectedids ="52"
Tuy nhiên, e lại chưa biết cách điền dữ liệu vào ô này thế nào. Mặc định của nó là selectedids = "11" là "công văn". Bây giờ e muốn chuyển nó thành "Quyết định" thì làm thế nào ạ.

E cũng đang tìm hiểu về tự động check box trong IE. Mong anh chị giúp đỡ hướng dẫn e viết code với ạ

<input name="ctl00_PlaceHolderMain_ctl00_TvwTransitionn0CheckBox" id="ctl00_PlaceHolderMain_ctl00_TvwTransitionn0CheckBox" type="checkbox">

Cảm ơn anh chị!
 
Top