จะตรวจสอบการตั้งค่าแมโครได้อย่างไรคะ
กระทู้เก่าบอร์ด อ.Yeadram

 3,255   13
URL.หัวข้อ / URL
จะตรวจสอบการตั้งค่าแมโครได้อย่างไรคะ

ขอเรียนสอบถามอาจารย์ทุกท่านนะคะ
ปกติค่าตั้งต้นของแมโครใน Access มักจะถูกปิดเอาไว้ตาม หมายเลข1 ในรูปค่ะ
ทำให้เกิดปัญหารันโค้ดไม่ได้ ผู้ใช้ก็คิดว่าโปรแกรมเราขัดข้อง
หนูจึงอยากหาวิธีว่า ทำอย่างไรจะให้มีข้อความแจ้งให้ผู้ใช้ทราบว่า แมโครถูกปิดอยู่
โดยให้เขาเปิดแมโครในตำแหน่งตาม หมายเลข2 ในรูป เสียก่อน

หรือไม่ก็เขียนโค้ดคำสั่งบังคับให้เปิดแมโคร หมายเลข2 เลยโดยอัตโนมัติที่เริ่มเปิดโปรแกรม
ขอบคุณค่ะ

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

1 @R21569
ให้ไปที่ "ตำแหน่งที่เชื่อถือได้" แล้วกดปุ่ม "เพิ่ม..." และเลือกโฟลเดอร์ที่มีไฟล์โปรแกรมของเราติดตั้งอยู่ เท่านี้ก็น่าจะทำให้ใช้งานได้โดยระบบจะไม่ตรวจเรื่องของ Macro Setting เพราะถือว่าไฟล์เราอยู่ในโฟลเดอร์ที่ไว้ใจได้

https://support.office.com/en-us/article/Add-remove-or-change-a-trusted-location-7ee1cdc2-483e-4cbb-bcb3-4e7c67147fb4
2 @R21571
ดูคำตอบ R17141 ใน http://www.thai-access.com/yeadram_view.php?topic_id=3735&page=1 ด้วย
3 @R21575
ขอบคุณค่ะอาจารย์
หากเป็นเครื่องที่เราใช้งานเองก็ไม่เป็นปัญหา
แต่ประเด็นอยู่ที่ผู้ใช้อื่นนำไปใช้กับเครื่องอื่น แล้วไม่เข้าใจวิธีการเซ็ทค่า อาจทำให้เกิดปัญหาได้
ประเด็นนี้แหละ ที่หนูอยากหาวิธีแสดง msg. เตือนให้ผู้ใช้ทราบเมื่อเริ่มเปิดโปรแกรมว่า แมโครถูกปิดอยู่ จำเป็นต้องเปิดแมโครก่อน
ประมาณนี้แหละค่ะอาจารย์
4 @R21577
ผมคิดว่าไม่น่าจะได้นะครับ เพราะโค้ดจะรันได้ต้องหลังจากผ่านด่านตรงนี้แล้ว วิธีนึงก็คือเขียนสคริปท์ใน .bat หรือ .cmd เพื่อสั่งให้โปรแกรม AddPath ทำงานก่อน แล้วก็ถึงเรียกโปรแกรมของเราทำงานเป็นลำดับถัดไป

อีกวิธีที่ไม่แน่ใจว่าทำได้แค่ไหน คือถ้าทุกเครื่องอยู่ในวินโดว์เน็ทเวิร์คเดียวกัน แล้วถ้าเราเป็น system admin (หรือขอให้ system admin ทำให้) ลองเข้าไปดู Group Policy ดูว่า Microsoft Office มี policy ให้เราจัดการเรื่อง Macro Setting หรือ Trust Location ได้ไหม จะได้สั่งจากศูนย์กลางเพียงเครื่องเดียว แล้วมันจะได้มีผลไปกับทุกเครื่องที่เราเลือกไว้ครับ
5 @R21578

จริงด้วยค่ะอาจารย์ หนูก็ลืมนึกถึงหลักการนี้ไปเลย
โค้ดให้แสดง msg.มันจะทำงานได้ก็ต่อเมื่อ Macro ต้องถูกเปิดก่อนแล้ว เข้าทำนองไก่กับไข่ใครเกิดก่อน
เอาเป็นว่าหนูล้มเลิกความคิดนี้แล้วล่ะ
ขอบคุณค่ะอาจารย์
6 @R21579
สำหรับปัญหาแบบนี้นะครับ
ประเด็นแรก: คือ เราจะไม่สามารถใช้เขียนคำสั่งใดๆ ภายในตัวไฟล์ MS Access เพื่อจัดการมันได้ ดังนั้นต้องเขียนโดยใช้ไฟล์ภายนอกทั้งตรวจสอบและจัดการมันก่อนเพียงครั้งเดียวตอนแรกเริ่มใช้งาน ซึ่งก็ทำได้ด้วยการเขียนเป็น vb Script หรือ Bat file จะง่ายที่สุด (ซี่งทั้ง 2 นามสกุลนี้เราสามารถใช้โปรแกรม Convert เป็น .exe ได้ในภายหลัง)

ประเด็นสอง: คือ การกำหนดให้โปรแกรม MS Access อ่าน แมโครได้นั้น ใน Options ของตัวโปรแกรมเอง หลักๆ สามารถทำได้ 2 อย่าง คือ
1. กำหนดในหัวข้อ Options > Trust Center: กดปุ่ม Trust Center Settings… > Macro Settings = Enable all macros
2. กำหนดในหัวข้อ Options > Trust Center: กดปุ่ม Trust Center Settings… > Trusted Locations > Add new location… = กำหนดที่อยู่พาธไฟล์เป้าหมาย

- ซึ่งในข้อหนึ่งจะเป็นการให้สามารถเปิดไฟล์ MS Access ได้ทั้งหมดไม่จำกัดตำแหน่ง ส่วนข้อสองจะเป็นการระบุตำแหน่งพาธที่สามารถใช้ได้เท่านั้น ซึ่งข้อดีข้อเสีย ศึกษาเองนะครับอธิบายยาว แต่โดยรวมแล้วถ้าเป็นไปได้กำหนดแบบข้อ 2 จะปลอดภัยกว่า

คราวนี้เราลองมาทำการเขียน vbScript กันก่อน เป็นอันดับแรกเพื่อความเข้าใจ
- สำหรับการตรวจสอบว่าเครื่องที่ใช้งานอยู่ กำหนดค่า Macro Setting เป็นอะไรอยู่
1. คลิ๊กเมาส์ขวาที่ Desktop เลือกเมนู New > Text Document

2. จะได้ไฟล์ New Text Document.txt เปล่าๆมา คลิ๊กๆเปิดไฟล์ขึ้นมา ใส่โค๊ดนี้ลงไป
On Error Resume Next

Dim WshShell
Set WshShell = CreateObject("WScript.Shell")
Dim objVer
Set objVer = CreateObject("Access.Application")

Dim strRegPath
Dim Access_Version
'เรียกเวอร์ชั่น MS Access
Access_Version = objVer.Version
'พาธรีจีสเตอร์เป้าหมาย
strRegPath = "HKEY_CURRENT_USER\Software\Microsoft\Office\" & Access_Version & "\Access\Security\VBAWarnings"
Dim SecurID
'อ่านค่ารีจีสเตอร์
SecurID = WshShell.RegRead(strRegPath)
If SecurID = 1 Then
    MsgBox "Enable all macros" & Chr(13) & "(เปิดใช้งานแมโครทั้งหมด)", , "Security VBA Warnings"
ElseIf SecurID = 2 Then
    MsgBox "Disable all macros with notification" & Chr(13) & Chr(10) & "(ปิดใช้งานแมโครทั้งหมดโดยมีการแจ้งให้ทราบ)", , "Security VBA Warnings"
ElseIf SecurID = 3 Then
    MsgBox "Disable all macros except digitally signed macros" & Chr(13) & Chr(10) & "(ปิดใช้งานแมโครทั้งหมดยกเว้นแมโครที่ถูกเซ็นชื่อแบบดิจิทัล)", , "Security VBA Warnings"
ElseIf SecurID = 4 Then
    MsgBox "Disable all macros without notification" & Chr(13) & Chr(10) & "(ปิดใช้งานแมโครทั้งหมดโดยไม่มีการแจ้งให้ทราบ)", , "Security VBA Warnings"
End If

objVer.Quit
WScript.Quit


3. จากนั้นไปที่เมนู File > Save As: เป็นชื่ออะไรก็ได้แต่นามสกุล vbs เช่น Macro.vbs และ Encoding: ANSI เซฟ แล้วปิดโปรแกรม notepad ไป

4. จะเห็นไฟล์ชื่อ Macro.vbs อยู่บน Desktop คลิ๊กๆเพื่อเรียกไฟล์ จะมีหน้าต่างข้อความ ค่า Options > Macro Setting ที่ตัวโปรแกรม MS Access ถูกกำหนดอยู่

แค่นี้ก่อนนะครับ เพราะมันมีเรื่องอีกยาว ขี้เกียจเขียนเหมือนกัน หากคิดว่าแนวทางนี้พอใช้ได้ ตอบกลับมานะครับ ผมค่อยมาต่อเรื่องของการสั่งแก้ไขค่าในรีจีสทรีด้วย vbScript อีกที

ปล. การเข้าถึง รีจีสทรี User ที่ใช้ใน MS Windows ต้องเป็นระดับ Admin
7 @R21585
ว้าว..ทดลองแล้ว มันตรวจสอบได้จริงๆด้วย หนูเริ่มจะเห็นแสงสว่างที่ปลายอุโมงแล้ว
ขอเรียนถามค่อ ว่า หากเราจะเอาโค้ดนี้ไปใส่ไน Access ขณะเปิดฟอร์มเริ่มต้น
จะเกิดผลเสียหายอะไรกับ Access ของเราหรือเปล่าคะ โดยจะดัดแปลงในส่วนของค่าที่ได้
เอาเป็น<>1 แทนเพียงอย่างเดียวIf SecurID <> 1 Then
MsgBox "แมโครยังไม่เปิดให้ใช้งาน)", , "Security VBA Warnings"

หนูยังไม่กล้าทำอะไรลงไป ขอรอฟังความเห็นจากท่านก่อน
ขอบคุณค่ะอาจารย์
8 @R21593
- โค๊ดจะอยู่ภายใต้ MS Access ไม่ได้ต้องทำไฟล์ขึ้นมาเรียกใช้ต่างหากครับ ซึ่งลักษณะนี้ก็มีอยู่สองแนวคิด เท่าที่ผมนึกออก คือ
1. สร้างไฟล์ vbscript ไว้ในโฟลเดอร์เดียวกับไฟล์ MS Access ที่ทำ และเมื่อไม่สามารถรันแมโครได้ ก็ให้ผู้ใช้เรียกไฟล์นี้ครั้งหนึง ก็จะเรียกใช้ แมโครได้ตามปกติ เสมือนเป็นไฟล์แก้ต่างหาก
2. สร้างไฟล์ vbscript ไว้เปิดไฟล์ MS Access เลย โดยก่อนเปิดก็จะตรวจสอบดูว่า MS Access กำหนด Option ไว้อย่างไร ถ้าไม่เป็นตามต้องการก็ให้แก้ก่อนแล้วค่อยเปิดไฟล์ MS Access

- สำหรับวิธีการทำให้ MS Access รันไฟล์ที่มีแมโครได้นั้น หลักๆก็ทำได้สองอย่างคือ
1. กำหนดใน Macro Settings = Enable all macros (ซึ่งจะใช้งานแมโครได้ทั้งหมดไม่ว่าอยู่โฟลเดอร์ใดก็ตาม)
2. กำหนดใน Trusted Locations > Add new location… = กำหนดที่อยู่พาธไฟล์เป้าหมาย (ซึ่งจะสามารถใช้งานไฟล์ที่มีแมโครได้เฉพาะโฟลเดอร์ที่เรากำหนดเท่า)

- ผมยกตัวอย่างแบบง่ายๆ ก่อนแล้วกันนะครับ คือการสร้างไฟล์ vbscript สำหรับเซ็ทค่า Macro Settings = Enable all macros โดยทำดังนี้:
1. คลิ๊กเมาส์ขวาที่ Desktop เลือกเมนู New > Text Document
2. จะได้ไฟล์ New Text Document.txt เปล่าๆมา คลิ๊กๆเปิดไฟล์ขึ้นมา ใส่โค๊ดนี้ลงไป
On Error Resume Next

Set WshShell = CreateObject("WScript.Shell")
Set objVer = CreateObject("Access.Application")

Access_Version = objVer.Version ' Get เวอร์ชั่นของโปรแกรม MS Access ออกมา (แน่นอนกว่าการเข้าไปอ่านในรีจีสทรี)

If Access_Version < 12.0 Then
    strRegPath = "HKEY_LOCAL_MACHINE\Software\Microsoft\Jet\4.0\Engines\SandBoxMode" ' ชื่อพาธ Name Key ของโปรแกรม MS Access ส่วนของ Jet Engines
    If WshShell.RegRead(strRegPath) <> 2 then
        WshShell.RegWrite strRegPath, 2, "REG_DWORD"
        chkSecurity = 1
    End If
    strRegPath = "HKEY_LOCAL_MACHINE\Software\Microsoft\Office\" & Access_Version & "\Access\Security\Level"
    If WshShell.RegRead(strRegPath) <> 1 then
        WshShell.RegWrite strRegPath, 1, "REG_DWORD"
        chkSecurity = 1
    End If
    If chkSecurity = 1 then
        MsgBox "ทำการกำหนด Security Level = Low เรียบร้อยแล้ว", , "Security"
    Else
        MsgBox "Security Level = Low อยู่แล้ว ไม่ต้องกำหนด", , "Low Security"
    End If
Else
    strRegPath = "HKEY_CURRENT_USER\Software\Microsoft\Office\" & Access_Version & "\Access\Security\VBAWarnings"
    If WshShell.RegRead(strRegPath) <> 1 then
        WshShell.RegWrite strRegPath, 1, "REG_DWORD"
        MsgBox "ทำการกำหนด Macro Settings = Enable all macros เรียบร้อยแล้ว", , "Security: VBA Warnings"
    Else
        'WScript.echo "กำหนดใช้งาน Macros ไว้อยู่แล้ว"
        MsgBox "Macro Settings = Enable all macros อยู่แล้ว ไม่ต้องกำหนด", , "Security: VBA Warnings"
    End If
End If


- จากนั้นเมื่อผู้ใช้เครื่องไหนเปิดไฟล์ MS Access แล้วฟ้อง Security Warnings ก็ให้ผู้ใช้รันไฟล์นี้ แล้วเปิดไฟล์ MS Access ใหม่อีกครั้ง

ปล. หากเราอยากทำไฟล์ .vbs ให้เป็น .exe ก็สามารถทำได้โดยการโปรแกรมประเภทนี้เช่น Vbs To Exe
ตัวอย่างไฟล์
9 @R21594
ขอเอาตามแนวคิดหมายเลข 1 เลยค่ะอาจารย์
- โค๊ดจะอยู่ภายใต้ MS Access ไม่ได้ต้องทำไฟล์ขึ้นมาเรียกใช้ต่างหากครับ ซึ่งลักษณะนี้ก็มีอยู่สองแนวคิด เท่าที่ผมนึกออก คือ
1. สร้างไฟล์ vbscript ไว้ในโฟลเดอร์เดียวกับไฟล์ MS Access ที่ทำ และเมื่อไม่สามารถรันแมโครได้ ก็ให้ผู้ใช้เรียกไฟล์นี้ครั้งหนึง ก็จะเรียกใช้ แมโครได้ตามปกติ เสมือนเป็นไฟล์แก้ต่างหาก
2. สร้างไฟล์ vbscript ไว้เปิดไฟล์ MS Access เลย โดยก่อนเปิดก็จะตรวจสอบดูว่า MS Access กำหนด Option ไว้อย่างไร ถ้าไม่เป็นตามต้องการก็ให้แก้ก่อนแล้วค่อยเปิดไฟล์ MS Access

หนูขอความกรุณาท่านช่วยปรับโค้ดเป็นแนวนี้ได้ไหมคะ
สมมติหนูมีไฟล์ Access ชื่อ Sample.mdb โดยให้อยู่ในโฟลเดอร์เดีวกับไฟล์ Open.vbs
การเปิดไฟล์โปรแกรม Sample.mdb ก็ให้เปิดจากไฟล์ Opeen.vbs เป็นหลักไปเลย โดยให้เช็ค macro ก่อน
หากไม่เป็น Enable all macros ก็ปรับแก้ก่อน แล้วค่อยสั่งเปิดไฟล์ Access เป้าหมาย
หากเป็น Enable all macros อยู่แล้วก็สั่งเปิดไฟล์ Access เป้าหมายเลย

ขอบคุณค่ะอาจารย์
10 @R21596
On Error Resume Next

Set WshShell = CreateObject("WScript.Shell")
Set objVer = CreateObject("Access.Application")
Access_Version = objVer.Version ' Get เวอร์ชั่นของโปรแกรม MS Access ออกมา (แน่นอนกว่าการเข้าไปอ่านในรีจีสทรี)
objVer.Quit

If Access_Version < 12.0 Then
    strRegPath = "HKEY_LOCAL_MACHINE\Software\Microsoft\Jet\4.0\Engines\SandBoxMode" ' ชื่อพาธ Name Key ของโปรแกรม MS Access ส่วนของ Jet Engines
    If WshShell.RegRead(strRegPath) <> 2 then ' ค่ามาตรฐานอยู่ที่ 1
        WshShell.RegWrite strRegPath, 2, "REG_DWORD"
        chkSecurity = 1
    End If
    strRegPath = "HKEY_LOCAL_MACHINE\Software\Microsoft\Office\" & Access_Version & "\Access\Security\Level"
    If WshShell.RegRead(strRegPath) <> 1 then ' ค่ามาตรฐานอยู่ที่ 2
        WshShell.RegWrite strRegPath, 1, "REG_DWORD"
        chkSecurity = 1
    End If
    If chkSecurity = 1 then
        MsgBox "ทำการกำหนด Security Level = Low เรียบร้อยแล้ว", , "Security"
    'Else
        'MsgBox "Security Level = Low อยู่แล้ว ไม่ต้องกำหนด", , "Low Security"
    End If
Else
    strRegPath = "HKEY_CURRENT_USER\Software\Microsoft\Office\" & Access_Version & "\Access\Security\VBAWarnings"
    If WshShell.RegRead(strRegPath) <> 1 then
        WshShell.RegWrite strRegPath, 1, "REG_DWORD"
        MsgBox "ทำการกำหนด Macro Settings = Enable all macros เรียบร้อยแล้ว", , "Security: VBA Warnings"
    'Else
        'MsgBox "Macro Settings = Enable all macros อยู่แล้ว ไม่ต้องกำหนด", , "Security: VBA Warnings"
    End If
End If

' ส่วนการเรียกไฟล์ ------------------------------------
CurrentPath = WshShell.CurrentDirectory
AppPath = WshShell.RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\MSACCESS.EXE\Path")
WshShell.Run("""" & AppPath & "\MSACCESS.EXE""" & """" & CurrentPath & "\Sample.mdb" & """")

Set WshShell = Nothing


ประมาณนี้ครับ
11 @R21597
อื่ม จริงๆ แล้วอยากแนะนำให้ใช้แบบกำหนดพาธใน Trusted Locations ซึ่งมันจะดูเป็นมืออาชีพมากกว่าการกำหนดตรงๆแบบ และปลอดภัยกว่าในกรณีหากคุณรับจ้างเขียนให้ลูกค้า แต่หากเขียนใช้กันเองก็ไม่เป็นไร

ซึ่งการกำหนดพาธใน Trusted Locations ก็สามารถทำได้ในรูปแบบเดียวกัน แต่เขียนโค๊ตค่อนข้างยาวเพราะต้องมีการตรวจสอบและใส่ชื่อ Key ที่ไม่ซ้ำเพิ่มลงไป แต่ข้อดีคือมันจะไม่ต้องกำหนด Macro Settings กลัว งง เลยขอใช้วิธีนี้ไปก่อนแล้วกันนะครับ ไว้ถ้าอยากได้อะไรที่มันซับซ้อนกว่านี้ค่อยถามมาใหม่ก็แล้วกันครับ
12 @R21599
ขอบพระคุณอย่างสูงค่ะอาจารย์
ได้ตรงตามที่ต้องการแล้ว หนูจะลองเอาไปปรับใช้ดูนะคะ

โค้ดยาวและซับซ้อนขนาดนี้ ท่านต้องสละเวลาและพลังความรู้จำนวนไม่น้อยเลย
บุญกุศลครั้งนี้ ขอให้ท่านและครอบครัวจงมีความสุขความเจริญตลอดปีใหม่และตลอดไปนะคะ
และขอให้อาจารย์ท่านอื่นๆจงมีความสุขความเจริญตลอดปีใหม่และตลอดไปเช่นเดียวกันนะคะ

สวัสดีปีใหม่ทุกๆท่านค่ะ
13 @R21601
ขอบคุณนะครับ ผมช่วยตอบผมก็ได้ฟื้นความรู้ MS Access ของผมด้วย เพราะงานผมไม่ได้เกี่ยวและใช้พวกนี้เลย
สวัสดีปีใหม่ล่วงหน้าเช่นกันครับ
@ ประกาศใช้งานเว็บบอร์ดใหม่ => บอร์ดเรียนรู้ Access สำหรับคนไทย
แล้วจะใส่ลิ้งอ้างอิงมาที่โพสต์เก่านี้หรือไม่ก็ตามสะดวกครับ
Time: 0.2590s