VBA Error : object variable or With block variable
กระทู้เก่าบอร์ด อ.Yeadram

 3,872   11
URL.หัวข้อ / URL
VBA Error : object variable or With block variable

เรียนอาจารย์ทุกท่าน
     ผมเจอ Error ขึ้นว่า Object variable or With block variable not set
เมื่อกด Debug พบว่ามีปัญหาที่บรรทัด Set objWorkbook = objexcel.Workbooks.Open(pathfile, , blnReadOnly, , _

ซึ่งเป็นที่เครื่องอื่นยกเว้นเครื่องผม (ทดสอบ 3 เครื่องเครื่องผมไม่มีปัญหาเครื่องเดียว) ผมลองตรวจสอบ Reference library แล้วพบว่าเลือกเหมือนกันครบครับ
ผมลองหาข้อมูล

ด้านล่างเป็น Function ที่มีปัญหาครับ

'ฟังก์ชั่นเปิดไฟล์ Excel และทำการ Replace ข้อมูลในไฟล์ Excel (ใช้เพื่อเตรียมไฟล์ Import เข้า table ต่อไปครับ)
Function Replace_ExcelUnMatch()

Dim blnHasFieldNames As Boolean, blnEXCEL As Boolean, blnReadOnly As Boolean
Dim lngCount As Long
Dim objexcel As Object, objWorkbook As Object
Dim colWorksheets As Collection
Dim strPassword As String


On Error Resume Next
Set objexcel = GetObject(, "Excel.Application")
If err.Number <> 0 Then
      Set objexcel = CreateObject("Excel.Application")
      blnEXCEL = True
End If
err.Clear
On Error GoTo 0


'blnHasFieldNames = True
blnHasFieldNames = False

strPassword = "vbNullString"

blnReadOnly = False

Set colWorksheets = New Collection

'Error ที่จุดนี้ครับ Set objWorkbook ....
Set objWorkbook = objexcel.Workbooks.Open(pathfile, , blnReadOnly, , _
      strPassword)
      
If objWorkbook.Worksheets(1).Cells(1, "F") = "Account No." Then
objWorkbook.Worksheets(1).Cells(1, "F") = "Account No"
objexcel.DisplayAlerts = False
objWorkbook.Save
objexcel.Save
End If

objWorkbook.Close False
Set objWorkbook = Nothing
If blnEXCEL = True Then objexcel.Quit
Set objexcel = Nothing

End Function

11 Reply in this Topic. Dispaly 1 pages and you are on page number 1

1 @R20503
1. ก็ต้องถามแบบกำปั้นทุบดินว่า อีก 3 เครื่องมีติดตั้ง Excel หรือเปล่า
2. ไฟล์ในตัวแปร pathfile สามารถเข้าถึงจากอีก 3 เครื่องได้จริงหรือไม่ มีเครื่องไหนใช้อยู่หรือไม่
3. โค้ดดูแปลกๆ เดาว่าคุณจะเปิดแบบ read only แต่คุณจะแก้ไข cell(1,"F") !!!
4. ลองแก้ไขอะไรสักอักษรนึงในโค้ด แล้วป้อนกลับคืน แล้วเอาโปรแกรมนี้ไป compile ที่เครื่องอื่นดู ดูผลว่าเป็นยังไง
2 @R20508
1. ทั้งหมดมี Excel ลงอยู่ในเครื่องครับ
2. pathfile เข้าได้หมดทุดเครื่องครับและไม่มีคนอื่นใช้ครับ(Copy File Excel ไปไว้ในเครื่อง แล้วเรียก pathfile จาก Dialog box ครับ)
3. ตั้งค่า boolean ที่จะเอาใช้ในคำสั่ง objexcel.Workbooks.Open ให้เป็น False แล้วครับ (blnReadOnly = False)
4. ไม่ค่อยเข้าใจครับอาจารย์ หมายถึงแก้ให้โค๊ดนี้มีจุดผิดเพิ่มหรือแก้แบบไหนครับ

ขอบคุณครับอาจารย์

หลักๆที่ต้องการสำหรับฟังก์ชันนี้คือไฟล์ Excel ที่จะเอามาใช้ Import แต่ละวันจะมี 1 column ที่ลงท้ายด้วยจุด . ทำให้ import แล้ว Error ครับผมเลยหาวิธีที่ User ไม่ต้องเข้าไปแก้ทุกๆครั้งก่อนที่จะ Import ข้อมูลครับ
3 @R20509
3. โทษที นึกว่าเป็น btnReadOnly เป็น built-in enumerate
4. ถ้าโค้ดที่ผ่านการคอมไพล์ไปแล้ว Access จะไม่เปิดให้คอมไพล์ซ้ำไงครับ ก็เลยแกล้งลบแล้วคีย์ใหม่ เพื่อหลอก Access ว่าโค้ดมีการแก้ไข จะได้ยอมให้เราคอมไพล์มันได้

ลองโค้ดนี้ดูครับ แต่ผมไม่ได้ทดสอบนะ

    Dim wb As Object
    
    Set wb = GetObject(pathfile)
    wb.Password = strPassword
    If wb.activesheet.Cells(1, "F") = "Account No." Then
        wb.activesheet.Cells(1, "F") = "Account No"
    End If
    wb.Save
    wb.Close

4 @R20510
เอาใหม่ ใช้ลดรูปจากโค้ดเดิมของคุณนั่นแหล่ะ (ที่ผมให้ไป ใช้ไม่ได้)

   dim xl as object
   dim wb as object

   set xl = createobject("excel.application")
   set wb = xl.workbooks.open(pathfile,,false,,strPassword)
   If wb.activesheet.Cells(1, "F") = "Account No." Then
        wb.activesheet.Cells(1, "F") = "Account No"
   End If
   wb.Save
   wb.Close: set wb = nothing
   xl.quit
5 @R20530
ลองมาแล้วครับอาจารย์ กลายเป็น Error 429 ActiveX component can't create object
ซึ่งเครื่องเดิมที่ใช้โค้ดเดิมได้ก็ใช้โค้ดใหม่ได้
เครื่องที่ใช้โค้ดเดิมไม่ได้ก็ใช้ไม่ได้ครับ

dim xl as object
   dim wb as object

'error ที่ set xl = ..... ครับจากที่ลองหาข้อมูลคาดว่าเป็นที่ไฟล์ dll ครับ (ถ้าหาวิธีแก้ได้จะมาตอบอีกทีครับ)
   set xl = createobject("excel.application")
   set wb = xl.workbooks.open(pathfile,,false,,strPassword)
   If wb.activesheet.Cells(1, "F") = "Account No." Then
        wb.activesheet.Cells(1, "F") = "Account No"
   End If
   wb.Save
   wb.Close: set wb = nothing
   xl.quit
6 @R20532
ลอง Decompile ไฟล์ดูยังครับ กรณีไฟล์มีปัญหาอ่าน Dll อ่านฟังก์ชั่นไม่ได้ เป็นกะบางเครื่องบ้าง อาการออกงง ให้ลอง Decompile ไฟล์นั้นดูครับ
วิธีการคือ เรียกไฟล์โปรแกรม MSACCESS.EXE โดยใข้พารามิเตอร์ /decompile แล้วตามด้วยชื่อไฟล์ที่ต้องการเปิด เช่น

"C:\Program Files\Microsoft Office\Office15\MSACCESS.EXE" /decompile "C:\ชื่อไฟล์คุณ.accdb"

ประมาณนี้ครับ อาจสร้างเป็น Shortcut หรือเรียกจาก ปุ่ม Start > Run หรือ Command Prompt อะไรก็ได้
7 @R20533
หรือจะทำเป็น Shortcut บนเมนู Sendto แบบนี้ก็ได้ครับ

Decompile File MS Access
8 @R20534
ผมลองทำ Decompile แล้วครับ
ผลกลายเป็นกดปุ่แล้วโปรแกรมหยุดทำงาน(นิ่งไปเฉยๆ) ส่วนที่เป็นฟังก์ชั่นที่มีปัญหาครับ

จากโค๊ด
Private Sub btnImport_Click()

pathfile = importFile
If pathfile = "" Then
Else
Call ReplaceExcel
...
...

   ตอน pathfile = importFile (เป็นส่วนเรียกใช้ฟังก์ชัน Dialogbox ที่เอาไว้เลือก Path file ) นั้นยังรันปกติคือมี Dialog ขึ้นมาให้เลือกไฟล์ครับ
   เมื่อเลือกไฟล์แล้วมันนิ่งไปเลย(กดปุ่มใหม่มันก็เข้า Dialogbox ใหม่) ครับ

ผมเลยเพิ่ม code check ค่าว่าโปรแกรมหยุดไปตอนไหนโดยใส่ msgbox เข้าไปในระหว่างคำสั่ง พบว่า msgbox pathfile ยังแสดงผล แต่ msgbox "After Call Function" ไม่ขึ้นแล้วครับเลยเข้าใจว่าโปรแกรมมันหยุดที่ function ที่มีปัญหาครับ

Private Sub btnImport_Click()

pathfile = importFile
If pathfile = "" Then
MsgBox "no file"
Else
MsgBox pathfile

Call ReplaceExcel
MsgBox "After Call Function"
...
...

จากนั้นด้วยวิธีเดียวกันผมพบว่าโปรแกรมเรียกใช้งานฟังก์ชั่นแล้วมาหยุดที่บรรทัดนี้ครับ
Function ReplaceExcel()
MsgBox "1" >>>> Message Box 1 ยังขึ้น
Dim xl As Object
Dim wb As Object
MsgBox "2" >>>> Message Box 2 ยังขึ้น
   Set xl = CreateObject("excel.application")
MsgBox "3" >>>> ตั้งแต่ Message Box 3 ไปไม่ขึ้นแล้วครับ
   Set wb = xl.workbooks.Open(pathfile, , False, , strPassword)
MsgBox "4"
   If wb.activesheet.Cells(1, "F") = "Account No." Then
MsgBox "5"
        wb.activesheet.Cells(1, "F") = "Account No"
MsgBox "6"
   End If
   wb.Save
   wb.Close: Set wb = Nothing
   xl.Quit
   
End Function

หลังจาก Decompile เมื่อเข้าโปรแกรมแบบปกติก็มีผลเหมือนกันครับคือนิ่งไปครับ

ขอบคุณครับอาจารย์
9 @R20537
ลองตัดให้เหลือแค่

   dim wd as object
   set wd = createobject("word.application")

ถ้ายัง error โค้ดเดิม ก็น่าจะแปลว่าไม่ใช่ปัญหาเฉพาะตัว excel แล้ว

อีก 3 เครื่องเป็น 64 bits หรือเปล่า ไม่แน่ใจว่าถ้าใช่ จะเป็นปัญหาหรือเปล่านะครับ แต่ถ้าเป็น 64 bits ก็แนะนำให้ decompile อย่างที่คุณ TTT ว่าไว้ แต่ต้องกดคีย์ SHIFT ค้างไว้จนทุกอย่างจะเสร็จสิ้น แล้วปิด Access ไป ห้ามเปิดอีก แล้วก็อปปี้ไปลง 3 เครื่องนั้น แล้วค่อยรันอีกที
10 @R20538
Function ReplaceExcel()
MsgBox "1" >>>> Message Box 1 ยังขึ้น
Dim xl As Object
Dim wb As Object
MsgBox "2" >>>> Message Box 2 ยังขึ้น
   Set xl = CreateObject("excel.application")
MsgBox "3" >>>> ตั้งแต่ Message Box 3 ไปไม่ขึ้นแล้วครับ
   Set wb = xl.workbooks.Open(pathfile, , False, , strPassword)
MsgBox "4"
   If wb.activesheet.Cells(1, "F") = "Account No." Then
MsgBox "5"
        wb.activesheet.Cells(1, "F") = "Account No"
MsgBox "6"
   End If
   wb.Save
   wb.Close: Set wb = Nothing
   xl.Quit
    
End Function

ข้อสังเกตุ
การอ้าง pathfile ได้ประกาศตัวแปรแบบ PUBLIC หรือเปล่าครับ เนื่องจากอยู่คนละ module
11 @R20540
function pathfile ไม่มีปัญหาครับ
เพราะอยู่ใน Module เดียวกัน(form เดียวกัน)และสามารถใช้งานฟังก์ชั่นนี้ได้ครับ
@ ประกาศใช้งานเว็บบอร์ดใหม่ => บอร์ดเรียนรู้ Access สำหรับคนไทย
แล้วจะใส่ลิ้งอ้างอิงมาที่โพสต์เก่านี้หรือไม่ก็ตามสะดวกครับ
Time: 0.2924s