Aplikasi saya saat ini menavigasi ke situs web vendor, masuk, membuka laporan, mengklik tombol unduh di belakang IFrame (yang merupakan kanker untuk bekerja), dan menekan tombol buka pada kotak dialog buka/simpan. Sekarang yang tersisa untuk fase proyek ini adalah membuat excel menunggu buku kerja baru dibuka, menarik informasi ke lembar baru, dan menutup buku kerja lainnya.

Masalahnya adalah apa pun yang saya coba, buku kerja baru tidak akan pernah terbuka saat makro berjalan. Jika saya menambahkan jeda dalam kode, semuanya berfungsi dengan baik. Saya sudah mencoba application.wait, sleep, DoEvents, dan bahkan msgbox. Aku agak bingung di sini.

'This clicks the button that initiates the open/save dialog box in IE
iWin.contentDocument.querySelector("a[title=Excel][onclick*=EXCELOPENXML]").Click

'set the name of the windows the program should look for
iStr = "Reports LeaveXpert Application - Internet Explorer"
eStr = "Case Detail.xlsx  [Protected View] - Excel"
'these are declared as longptr
leHwin = 0
cdHwin = 0

'Grabs the windows handle for the IE window
leHwin = FindWindow(vbNullString, iStr)
'Makes sure the IE window is active
i = SetForegroundWindow(leHwin)
'a little bit of delay
Application.Wait DateAdd("s", 5, Now)
'Send the key combination for the open button to the open browser
Application.SendKeys "%{O}"


cdHwin = 0
Debug.Print cdHwin

'this should wait for the new spreadsheet to open but instead the application hangs here and the new spreadsheet never opens.
Do While cdHwin = 0

    'various methods of having the program wait that i've tried
    
    'DoEvents
    'Application.Wait (Now() + TimeValue("00:00:01"))
    'Sleep 1000
    
    'this should set the variable to the windows handle of the new sheet once it opens causing the loop to stop
    cdHwin = FindWindow(vbNullString, eStr)
    
    'This just keeps giving me 0 as an output
    Debug.Print cdHwin
Loop

'we never get to this line of code unless I add a break somewhere in the loop, then the sheet opens and I get the windows handle as output.
Debug.Print cdHwin

MEMPERBARUI:

AKHIRNYA BEKERJA!!!!!!!!!!!!!!!

Saya harus memikirkan kembali pendekatan satu tombol saya untuk implantasi, tapi itu harga yang cukup kecil untuk dibayar. Ini telah menjadi proyek yang tidak aktif selama lebih dari 2 minggu dan telah membawa saya jauh lebih banyak waktu daripada yang saya perkirakan, sebagian besar karena IFrame menjadi kanker absolut (saya sangat membenci mereka). Tapi saya telah belajar banyak untuk membuat bagian pertama ini berhasil. Sekarang untuk mulai menyatukan dua sumber data relevan lainnya ke dalam spreadsheet. Semakin banyak saya belajar tentang pemrograman komputer; semakin saya menyadari betapa sedikitnya yang saya ketahui tentangnya.

Oh dan Mathieu-Guindon adalah pahlawan mutlak!

2
Rational Redneck 11 Mei 2021, 23:36

1 menjawab

Jawaban Terbaik

Bagaimana jika kita membiarkan Excel melakukan tugasnya, dan mengikuti aliran paradigma yang digerakkan oleh peristiwa / tidak sinkron?

Kelas Excel.Application memunculkan sejumlah peristiwa yang dapat Anda tangani di modul kelas mana pun, tetapi modul ThisWorkbook dapat melakukannya - Anda mendeklarasikan variabel tingkat modul WithEvents:

Option Explicit
Private WithEvents AppEvents As Excel.Application

Dan kemudian Anda menginisialisasinya dengan referensi objek Application, mungkin saat terbuka - jika kita berada di modul ThisWorkbook, kita mewarisi properti Application dari basis Excel.Workbook kelas:

Option Explicit
Private WithEvents AppEvents As Excel.Application

Private Sub Workbook_Open()
    Set AppEvents = Me.Application
End Sub

Mendeklarasikan variabel WithEvents membuatnya tersedia di dropdown kiri atas, dan kemudian kita dapat memilih anggota untuk diterapkan dengan dropdown kanan atas:

selecting 'AppEvents' in the top-left dropdown

Salah satu peristiwa yang dapat kita tangani pada tingkat Application, adalah peristiwa WorkbookOpen yang memberikan kita referensi Wb As Workbook ke buku kerja yang baru saja dibuka:

Private Sub AppEvents_WorkbookOpen(ByVal Wb As Workbook)

End Sub

Di sini Anda dapat mencegat setiap buku kerja yang terbuka selama sesi yang mendukung makro, selama referensi AppEvents ini tetap berada dalam cakupan - yaitu, hingga ThisWorkbook ditutup.

Jadi ThisWorkbook mungkin terlihat seperti ini:

Option Explicit
Private Const CaseDetailFileName As String = "Case Detail.xlsx"
Private WithEvents AppEvents As Excel.Application

Private Sub Workbook_Open()
    Set AppEvents = Me.Application
End Sub

Private Sub AppEvents_WorkbookOpen(ByVal Wb As Workbook)
    If Wb.Name = CaseDetailFileName Then
        DoThingWithCaseDetailWorkbook Wb
    End If
End Sub

Kemudian Public Sub DoThingWithCaseDetailWorkbook(ByVal book As Workbook) dapat didefinisikan dalam modul standar apa pun dan memiliki akses ke status/variabel modul apa pun yang ditetapkan sebelum peristiwa WorkbookOpen diaktifkan.

Sekarang fakta bahwa file sedang dibuka dalam mode terlindungi (dari lokasi yang tidak dipercaya?) Mungkin mengganggu ini, tetapi kemudian harus ada cara untuk mendapatkan skrip untuk menyimpan file di tempat lain jika itu masalah.

2
Mathieu Guindon 12 Mei 2021, 01:41