ขอโค้ดที่สามารถ Copy ไฟล์ Access ไปไว้ที่อื่นค่ะ
กระทู้เก่าบอร์ด อ.Yeadram

 8,689   24
URL.หัวข้อ / URL
ขอโค้ดที่สามารถ Copy ไฟล์ Access ไปไว้ที่อื่นค่ะ

หนูลองค้นหาในบอร์ดนี้แล้วแต่ยังไม่ตรงตามต้องการ เลยขอตั้งคำถามใหม่ดังนี้นะคะ

หนูอยากทราบว่าเราสมารถสร้างโค้ดเพื่อให้มัน Copy ไฟล์ Access ของเราที่กำลังจะปิดการทำงาน(Quit) ไปไว้ที่อื่น อีกตัวหนึ่งก่อน แบบอัตโนมัติ ได้ไหมคะ

เช่นสมมติว่าหนูมีไฟล์ตัวหนึ่งชื่อ Sample-A.mde ซึ่งเก็บไว้ที่ไดร์ฟ C:\
เป็นไฟล์หลัก ที่ใช้ทำงานอยู่เป็นประจำ

โดยหนูอยากให้ทุกครั้ง ที่จะจบการทำงานแล้ว ให้มัน Copy ไฟล์หลัก Sample-A.mde (ที่กำลังจะปิด) ส่งไปไว้ที่ไดร์ฟ D:\ เพื่อเป็นไฟล์สำรองไว้อีกตัวหนึ่ง

โดยใช้ชื่อไฟล์สำรองนี้ว่า Sample-B.mde ทุกอย่างเหมือนกับไฟล์ต้นฉบับทุกประการ ยกเว้นชื่อไฟล์เท่านั้นที่ให้มันแตกต่างกัน

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

หนูไม่ทราบว่าต้องทำอย่างไร ปัจจุบันเมื่อเสร็จการทำงานแล้ว หนูจะใช้วิธี Copy ไฟล์ต้นฉบับ นำไป Paste ในตำแหน่งใหม่ที่ต้องการเป็นระยะๆค่ะ

ขอรบกวนอาจารย์ โปรดแนะนำด้วยนะคะ

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

1 @R04749
มันแค่กำลังจะปิด แต่ก็คือยังอยู่ใน Process อยู่ (แรมและซีพียูของเครื่องกำลังใช้งานไฟล์นี้อยู่) ผมคิดว่า น่าจะก็อปปี้ตัวเองไม่ได้

วิธีหนึ่งที่คิดได้คือ การย้าย Process ไปไว้ที่โปรแกรมอื่นแล้วค่อยสั่งการ copy
1) สั่ง VBA เขียน สคริปต์ Bat file
1.1) ในสคริปต์ ต้องมีคำสั่ง copy file c:\sample-A.mdb ไปเป็น D:\sample-B.mdb (วางทับของเดิมโดยไม่ต้องถาม)
1.2) ในสคริปต์นั้น สั่งการให้ "รอ" ประมาณ 3 วินาที (ช่วงระยะเวลาให้ Access ปิดตัวได้สมบูรณ์ก่อน) แล้วค่อยเริ่มทำงานคำสั่งใน 1.3
1.3) ในสคริปต์นั้นสั่ง Copy - ลบไฟล์สคริปต์ตัวเอง - หยุดทำงาน

2) สั่ง VBA เซฟไฟล์สคริปต์นั้น และรันทันที
3) สั่งปิด Access ตัวปัจจุบัน (Quit)

2 @R04751
Dim CopyString As String
    CopyString = "CMD.EXE /C COPY " & [source] & ".mdb" & _
               " " & [Target]
            Call Shell(CopyString, 0)
            
            
MsgBox (" copyข้อมูลเรียบร้อย "), 64


โหลดตัวอย่างโปรแกรมและสอบถามปัญหาต่าง ๆของการใช้งาน ms access เพิ่มได้ที่
http://access.crtrading.net
3 @R04756
ขอบคุณอาจารย์ทั้งสองท่านค่ะ

แนวคิดของ อ. yeadram น่าจะเวอร์คนะคะ แต่หนูขอเพิ่มอีกประเด็นนะคะ คือ ชื่อไฟล์ต้นฉบับ ถ้าเป็นแบบไม่ต้องคำนึงถึงชื่อ ได้ไหมคะ ให้เป็นแนวเคอร์เรนท์ไฟล์ คือไฟล์ต้นฉบับจะเป็นชื่ออะไร ก็สามารถทำงานได้หมด อะค่ะ
ดูๆแล้วโค้ดนี้ คงต้องสลับซับซ้อนมากที่เดียวนะคะ

สำหรับโค้ดที่ อ. akk กรุณาแนะนำนั้น

Dim CopyString As String
    CopyString = "CMD.EXE /C COPY " & [source] & ".mdb" & _
               " " & [Target]
            Call Shell(CopyString, 0)
      
MsgBox (" copyข้อมูลเรียบร้อย "), 64

หนูไม่เข้าใจวิธีนำไปใช้ค่ะ หนูลองนำไปใส่ใน Event ..on click แล้วมัน error ค่ะ ตอนนี้กำลังพยายามหาวิธีอื่นอยู่ แต่ยังไม่สำเร็จค่ะ
4 @R04758
พอดีหนูไปค้นไปเจอโค้ดโมดูล อันหนึ่ง เห็นมีคำสั่ง Function fCopy อยู่ซึ่งไม่ทราบว่า โค้ดนี้ เขาใช้ทำงานอะไร ใช้กับที่หนูต้องการได้ไหม หากได้... ใช้อย่างไรคะ

Function fCopy(strDest As String, strSrc As String)
Dim fs As Object, strTime As String
Set fs = CreateObject("Scripting.FileSystemObject")
fs.copyfile strDest, strSrc, True
End Function

ขอรบกวนอาจารย์ด้วยค่ะ
5 @R04759
ตามค้นหาไปจนเจอ เป็นโค้ดของ อ. renoo อยู่ที่นี่ค่ะ

http://www.thai-access.com/yeadram_view.php?topic_id=266&page=1

หนูเก็บเฉพาะโมดูลเอาไว้นาน จนลืมแล้วว่าได้โค้้ดนี้มาจากไหน พึ่งจะค้นเจอเดี๋ยวนี้เองค่ะ
ตอนนี้หนูทำได้แล้ว ทำตามที่ อ. renoo ท่านแนะนำไว้แหละค่ะ แต่...ติดปัญหาตรงที่ว่า ไฟล์หลักต้นฉบับนั้น ห้ามเปลี่ยนชื่อ และ ต้องอยู่ในตำแหน่งที่แน่นอน

หนูจึงขอถามต่อว่า ทำอย่างไรให้สามารถเปลี่ยนแปลงไฟล์หลักต้นฉบับแล้ว คำสั่งยังคงทำงานได้ปกติค่ะ
6 @R04761
อย่างที่ อ.เรณู แนะนำ นั่น เป็นงานอีกแบบ คือ งานของเขา จะแยก Access ออกเป็นสองส่วน คือ Back-end กับ front-end

โค้ดหรือแนวคิดทั้งหมดของ อ.เรณู คือ จะสำรองเฉพาะ ตัว Back-end และบ้าง
อาจจะ (เดานะครับ) เพื่อประโยชน์ในการต่อเนื่องของงาน กรณี ไฟล์ Back-end ตัวแรกมีปัญหาในทันทีทันใด

เช่น ไฟล์โปรแกรม Front-end ของคุณมาลี ชื่อ F1 วางไว้ใน Drive C
ลิงค์ข้อมูลมาทำงานจากไฟล์ Back-end ชื่อ B1 ซึ่งก็วางอยู่ใน Drive C เช่นกัน
เมื่อต้องการ Backup ในความหมายของโค้ดของอ.เรณู คือ สั่งการ ให้ B1 สำรองตัวเองไปไว้ที่ Drive D ที่บอกว่าโดยไม่เปลี่ยนชื่อ และให้อยู่ใน โฟลเดอร์เดิม ก็คงเพราะว่า

ถ้าหากวันใดวันหนึ่ง F1 กำลังทำงานอยู่ (ซึ่งโดยปกติจะลิงค์ตารางจาก B1) ปรากฎว่า B1 มันมีปัญหาติดขัด หรือติดล็อกอะไรซักอย่าง ตัว F1 จะสามารถเปลี่ยนลิงค์ไปที่ B2 ได้อย่างง่ายดายโดยทีงานไม่ติดขัด การทีคงชื่อและระดับโฟลเดอร์เอาไว้ คงเพราะเพื่ออย่างนี้ละมั้งครับ (ขอย้ำว่าเดา)

แต่ถ้างานของคุณมาลี เป็น Access ที่ใช้ตัวเดียว คือเป็นทั้งตัวจัดการข้อมูลและเป็นตัวเก็บข้อมูล (ไม่มี Back-end และ front-end) ก็ต้องลองปรับเปลี่ยนโค้ดดูครับ และผมก็ยังไม่เคยลอง บอกตรงๆ ไม่แน่ใจว่า Windows จะยอมให้
Access สั่งจำลองตัวเองได้หรือไม่ (แต่ไวรัสมันทำได้แฮะ Access ก็น่าจะทำได้) ที่ผมกลัวว่ามันไม่ได้เพราะว่า ขณะที่ Access ยังรันอยู่นั้น ข้อมูลบางอย่าง บางตารางอาจจะยังผูกอยู่กับฟอร์ม หรือกำลังประมวลผลค้างคาอะไรอยู่ ดังนั้น กลัวว่า การก็อปปี้ตัวเอง อาจจะทำให้เกิด Error หรือข้อมูลที่ติดล็อคอยู่ขณะนั้นมีการเสียหายได้ ดังนั้นคิดว่า VBA หรือ Windows น่าจะไม่ยอมให้กระทำ

แต่ว่า.................. ผมแค่เดา ยังไม่ลองครับ
ผมก็เลยตัดปัญหาด้วยการ "ไม่ให้ Access สั่งก็อปปี้ตัวเอง"
แต่ผมใช้ Batch file สั่งให้ Copy แทน (โดยพยายามให้แน่ใจก่อนว่า Access ได้ปิดตัวเอง ปลดล็อคเรคคอร์ดต่างๆ สมบูรณ์ดีแล้ว)

ส่วนโค้ดเอาไว้ก่อนนะครับ ผมจำคำสั่ง ให้ Batch file มัน รอ 3 วินาที ไม่ได้ ว่าจะไปดูโค้ดเก่าๆ ที่ผมเขียนไว้ใช้ที่ออฟฟิศก่อน ถึงจะเอามาตอบ อิอิ
7 @R04763
ขอบคุณค่ะอาจารย์ yeadram งานนี้หนูไม่รีบ หนูรอได้ค่ะ

งั้นหนูขอขยายความคืบหน้าเพิ่มเติมหน่อยนะคะ คือขณะนี้หนูใช้โค้ดด้านล่างนี้ มันก็สามารถ Copy ไฟล์ฐานข้อมูลไปยังปลายทางที่ไดร์ฟ C:\แฟ้มข้อมูลสำรอง\Sample-B ได้ตามต้องการแล้วค่ะ

Private Sub Form_Close()
Dim fold
        Set fold = CreateObject("Scripting.FileSystemObject")
        newFDR = "C:\แฟ้มข้อมูลสำรอง"
        If Not fold.FolderExists(newFDR) Then
        fold.CreateFolder (newFDR)
        End If
        If MsgBox("ต้องการสำรองข้อมูล...", vbQuestion + vbOKCancel, "โปรดทราบ") = vbOK Then
        fCopy "D:\Sample-A.mdb", "C:\แฟ้มข้อมูลสำรอง\Sample-B.mdb"
        MsgBox "สำรองข้อมูลเสร็จแล้ว", vbOKOnly, "รายงานผล"
        End If
End Sub

แต่มันติดอยู่นิดเดียวตรงที่ว่า (สีแดง) หากไฟล์ต้นทางถูกเปลี่ยนเป็นชื่ออื่น หรือย้ายไปอยู่ตำแหน่งอื่น (ที่ไม่ใช่ไดร์ฟ D:\) แล้วมันก็จะ Error Copy ไม่ได้ค่ะ

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

เคยอ่านเจอว่ามีคำสั่ง CurrentProject.Path หรือ CurrentProject.Name หนูไม่แน่ใจว่าจะใช้แก้ปัญหานี้ได้หรือเปล่า ลองมั่วทดลองใช้ดูแล้วแล้ว มันไม่ได้ มันไป Error ที่โค้ดในโมดูล ตามรูปตัวอย่างค่ะ



ขออนุญาตให้ข้อมูลเพิ่มเติมเพียงแค่นี้นะคะ อาจารย์จะได้ไม่ต้องเสียเวลาเขียนโค้ดตั้งแต่ต้นทั้งหมด

ขอขอบคุณอีกครั้งค่ะ
8 @R04764
เอาแบบรีบๆ ไปก่อนนะครับ
คำสั่งนี้ ผมสร้างฟอร์มเปล่า 1 ตัว ไม่ผูกกับข้อมูลใดๆ (มั่นใจได้ว่าไม่มีเรคคอร์ดใดกำลังถูกใช้งานหรือถูกล็อก)
ผมสร้าง ปุ่มคำสั่ง 1 ตัว แล้วเขียนโค้ดในเหตุการณ์ Onclick

ใน VBA ผมเพิ่มไลบรารี่ Microsoft scripting runtime

Private Sub Command0_Click()
Dim FSO As New FileSystemObject
FSO.CopyFile CurrentProject.Path & "\" & CurrentProject.Name, "D:\" & CurrentProject.Name, True
set FSO = nothing
End Sub


เมธอด CopyFile ของออปเจคนี้ สามารถระบุได้ 3 อาร์กิวเมนต์
1 พาธและชือไฟล์ต้นทาง (เปลี่ยนแปลงได้ครับ)
2 พาธและชื่อไฟล์ปลายทาง (เปลี่ยนแปลงได้เช่นกัน)
3 หากจำเป็นต้องทับไฟล์เดิม ต้องการให้ทับเลยหรือไม่


กรณีของคุณมาลี หากต้องการให้ยืดหยุ่น เปลี่ยนแปลงพาธหรือชื่อไฟล์ คุณมาลี อาจจะเพิ่มขั้นตอนการ Browse ได้ครับ น่าจะเป็นแล้ว..

เช่น Dim pth as string
pth = inputbox(........,"โปรดระบุพาธ")
อันนี้ เหมาะสำหรับใช้กับ User ที่พอจะรู้หลักหน่อย

ส่วนถ้าใช้กับ User ที่ทั่วไปจริง แนะนำให้หา คอนโทรลพวก Common Dialog มาใช้ร่วมครับ


โค้ดนี้ผมลองแล้ว ใช้ได้ครับ ง่ายดี แต่อย่างที่บอกผมกล้ามั่นใจ เพราะว่า ฟอร์มของผมเป็นฟอร์มเปล่า ไม่มีการใช้ข้อมูลในขณะนั้น ดังนั่นมั่นใจว่า ไม่มีข้อมูลติดล็อก หรือมีข้อมูลที่กำลังทำงาน การ ก็อปปี้ไฟล์ จึงสมบูรณ์ ร้อยเปอร์เซนต์
9 @R04765
ขอมาเฝ้าดูด้วยนะครับ คำถามของคุณมาลีน่าสนใจดีครับ
รบกวนคุณมาลี ช่วยสรุปเล็ก พอให้ผมผู้น้อยได้รับรู้บ้าง เมื่อคุณทำได้แล้วบ้างนะครับ
ขอบคุณ ท่านอาจารย์ และคุณมาลีด้วยครับ :-)
10 @R04766
ทันใจดีจังเลยค่ะอาจารย์
กำลังจะปิดเครื่อง นึกเอะใจ เลยแวะเข้ามาดู เจอความช่วยเหลือของท่านพอดี
หนูขอยกยอดไปทดสอบพรุ่งนี้เช้านะคะอาจารย์ ได้เรื่องอย่างไรจะรีบรายงานให้ท่านและเพื่อนๆสมาชิกได้ทราบค่ะ

ขอบคุณค่ะ
11 @R04769
ขอรายงานผลค่ะอาจารย์
หนูคัดลอกเอาโค้ดที่ท่านแนะนำ ไปใส่ทั้งชุดเลย โดยมีเงื่อนไขเดียวกัน คือ สร้างฟอร์มเปล่าๆ แบบไม่ผูกยึดกับอะไรทั้งสิ้น แล้วก็ใส่โค้ดนี้ลงไป ผลคือ มันไม่ยอมผ่านให้ค่ะอาจารย์

โดยขึ้น error ตามในรูปนี้



หนูไม่ทราบว่าผิดตรงไหน รีบรายงานผลให้ท่านทราบก่อน เดี๋ยวหนูจะลองเข้าไปสแกนดูทุกตัวอักษรว่า หนูทำอะไรผิดพลาดไปหรือเปล่า

ขอบคุณค่ะ
12 @R04770
เพิ่ม ไลบราลี่หรือยังครับ
ถ้าไม่เพิ่ม ไม่คิดจะเพิ่ม หรือหาไม่เจอ ก็จำลองเอา อย่างที่คุณ มาลีเคยทำนั่นแหละครับ ไม่งั้นมัน จะ Error เพราะมันไม่รู้จัก Object Class ของตัวแปร FSO

Dim FSO as object
        Set FSO = CreateObject("Scripting.FileSystemObject")
แล้วค่อยใช้
        FSO.copyFile.......
13 @R04771
ได้แล้วค่ะอาจารย์
ปรับแก้ไขใหม่ตามที่ท่านแนะนำ...

Private Sub Command0_Click()
        Dim FSO As Object
        Set FSO = CreateObject("Scripting.FileSystemObject")
        FSO.CopyFile CurrentProject.Path & "\" & CurrentProject.Name, "D:\" & CurrentProject.Name, True
        Set FSO = Nothing
End Sub

สรุปคือ..ใช้ได้เรียบร้อยตามที่ต้องการ
ขอขอบคุณอาจารย์ ที่ให้ความกรุณาหนูเสมอค่ะ
14 @R17920
คุณมาลี และอาจารย์ทุกท่านคะ ขอถามต่อยอดเพิ่มเติมนะคะ
หนูเปิดงานAccess2 แล้วเปิดฟอร์มF1 ถ้าหนูสร้าง TextBox ชื่อ Text1 บนฟอร์ม F1
ในText1 มีข้อมูล C:\Access1.accdb (ซึ่งเป็น Path ไฟล์อีกไฟล์หนึ่ง ซึ่งไม่ใช่ไฟล์ที่เปิดใช้ปัจจุบัน)
เมื่อหนูคลิกไปที่ Text1นี้ แล้วให้ copy ไฟล์ที่มีชื่อและตำแหน่ง Path อยู่ใน Text1 นี้ ไปใว้ที่ D:\Access1.accdb
จะต้องแก้ไข code ของคุณมาลีอย่างไรคะ
เพราะ Code ของคุณมาลี จะ copy ไฟล์ Access ที่กำลังเปิดใช้อยู่ตัวนั้น
แต่ของหนูเป็นไฟล์ตัวอื่นค่ะ
ขอบคุณค่ะ
15 @R17921
        Dim FSO As Object
        Set FSO = CreateObject("Scripting.FileSystemObject")
        FSO.CopyFile Forms("F1")!Text1, Replace(Forms("F1")!Text1,"C:","D:",1,1), True
        Set FSO = Nothing
16 @R17922
ขอบคุณค่ะจะลองเอาไปใช้ก่อนนะคะได้ผลอย่างไรจะมารายงานผลนะคะ
17 @R17938
อาจารย์.(R17921)
จาก Codeที่ให้มา ลองทำแล้ว จะขึ้น Debug ว่า ไม่พบ ฟอร์ม F1
หนูทดลองจำลองงานเหมือนทุกอย่างใน Code ค่ะ
แต่จะขึ้น Debug ว่า ไม่พบ ฟอร์ม F1
รบกวนอาจารย์ช่วยดูให้หนูหน่อยค่ะ
18 @R17939
ก็แปลว่าฟอร์มไม่ใช่ชื่อ F1   แก้ชื่อให้ถูกเท่านั้นเอง
19 @R17940
ขอบคุณค่ะอาจารย์
ทำตามที่อาจารย์บอก ออกแล้วค่ะ
ขอบคุณอีกครั้ง..
20 @R17943
อาจารย์คะ
ขอถามต่อไปอีกนิดค่ะ
(R17921)บรรทัดที่เขียนว่า
FSO.CopyFile Forms("F1")!Text1, Replace(Forms("F1")!Text1,"C:","D:",1,1), True

คำถามคือ ถ้าตรง "C:" ไม่ใช่ C แต่ให้เป็นไปตาม path ที่อยู่ใน Text1
เราควรจะเขียนคำสั่งอย่างไรคะ
@ ประกาศใช้งานเว็บบอร์ดใหม่ => บอร์ดเรียนรู้ Access สำหรับคนไทย
แล้วจะใส่ลิ้งอ้างอิงมาที่โพสต์เก่านี้หรือไม่ก็ตามสะดวกครับ
Time: 0.2824s