แสดงกระทู้

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - สันติสุข

หน้า: [1] 2 3 4 ... 25
1
- ที่ถามว่า เข้าใจถูกไหม ถ้าจะใช้ภาษาบ้านๆ ก็พอจะอนุโลมได้ว่าถูกครับ

- DoCmd.RunSQL สามารถอ้างคอนโทรลของฟอร์ม (เท็กซ์บ็อกซ์, คอมโบบ็อกซ์, ...) ได้โดยตรงใน SQL โดยไม่ต้องหาค่าของคอนโทรลเหล่านั้นออกมาแล้วแปลงเป็นเท็กซ์เพื่อสร้าง SQL อีกที เช่นเราสามารถเขียน DoCmd.RunSQL "insert into table1 (field1, field2) values (Forms!Form1!Text1, Forms!Form1!Combobox2)" โดยไม่จำเป็นต้องเขียนเป็น

Dim T1 As  string
Dim T2 as  string

T1 = Forms!Form1!Text1
T2 = Forms!Form1!Combobox2
DoCmd.RunSQL "insert into table1 (field1, field2) values ('" & T1 & "', '" & T2 & "')"

หรือ

DoCmd.RunSQL "insert into table1 (field1, field2) values ('" & Forms!Form1!Text1 & "', '" & Forms!Form1!Combobox2 & "')"

แต่การใช้ DoCmd object จะไม่ถูกควบคุมโดยไลบรารี่ DAO (เหมือน 2 คนทำงานให้สำเร็จเหมือนกันได้ แต่คนละเจ้านาย)

2
DAO.Recordset คือการอ้างถึงคลาสที่ชื่อ Recordset ในไลบรารี่ DAO (จะไม่เขียน DAO. ก็ได้ถ้า 1. เราแน่ใจว่าเรามีคลาสชื่อ Recordset และชื่อนี้ไม่ซ้ำกับคลาสอื่นในไลบรารี่ตัวอื่นในระบบเรา หรือ 2.มีซ้ำในไลบรารี่อื่นๆด้วย แต่เราอ้างถึงไลบรารี่ลำดับแรกที่พบ ซึ่งเราก็ต้องมั่นใจด้วยว่าลำดับของไลบรารี่เรียงถูกต้องแล้ว)

Dim RST As DAO.Recordset  เป็นการสร้างตัวแปรออปเจค RST ที่จะมีคุณสมบัติตามคลาส Recordset

CurrentDb.OpenRecordset("tb_newmember") ให้ชุดเรคอร์ดที่ได้จากเทเบิล tb_newmember และเทเบิลนี้อยู่ในฐานข้อมูลที่โค้ดเรากำลังทำงาน

Set RST = CurrentDb.OpenRecordset("tb_newmember") ให้ตัวแปรออปเจค RST ชี้ไปยังชุดเรคอร์ดที่ได้มาจากคำอธิบายข้างบน

RST.AddNew เป็นเมธอดที่บอกให้ระบบรู้ว่าเราต้องการให้เตรียมพื้นที่สำหรับเรคอร์ดใหม่ในชุดเรคอร์ดในตัวแปรออปเจค RST

RST.Update เป็นเมธอดที่สั่งให้ตัวแปรออปเจค RST เขียนเรคอร์ด กรณีนี้คือเรคอร์ดในพื้นที่ ที่ได้จาก RST.AddNew

Set RST = Nothing บอกให้ตัวแปรออปเจค RST เลิกชี้ไปยังออปเจคใดๆที่มันเคยชี้อยู่

3
เช็คว่ามีจำนวนเรคอร์ดใน ID เดียวกันตัวไหนที่เกิน 10  เพราะบอกมาว่ามีฟิลด์แค่ Field1 - Field10 เท่านั้น

4
ใช้คำสั่ง SQL ล้วนๆคงไม่ได้ ต้องใช้ VBA ด้วย โค้ดนี้ต้องปรับแก้ให้ใส่ ' ' คร่อม ถ้า data type ของ ID, Num, Fieldxx เป็น Text ด้วยนะครับ

Public Sub xxx()
    Dim DB  As DAO.Database
    Dim RS  As DAO.Recordset
    Dim LastID  As Variant
    Dim I   As Integer
   
    Set DB = CurrentDb
    Set RS = DB.OpenRecordset("select * from Table1 (order by ..., ถ้ามี)")
    Do Until RS.EOF
        If RS!ID <> LastID Then
            I = 1
            DB.Execute "insert into Table2 (ID, Field1) values (" & CStr(RS!ID) & ", " & CStr(RS!Num) & ")", dbFailOnError
        Else
            I = I + 1
            DB.Execute "update Table2 set Field" & CStr(I) & " = " & CStr(RS!Num) & " where ID = " & CStr(RS!ID), dbFailOnError
        End If
        LastID = RS!ID
           
        RS.MoveNext
    Loop
    RS.Close: Set RS = Nothing
End Sub

5
ไม่มีทางเพิ่มเกิน 255 ฟิลด์ครับ ให้สร้างอีกเทเบิลที่มีฟิลด์ Primary Key เหมือนเทเบิลแรก และย้ายฟิลด์ส่วนเกินไปไว้เทเบิลที่สองแทน พร้อมกับสร้าง Relationships (ในริบบอน Database Tools) จากเทเบิลแรกไปเทเบิลที่สอง โดยกำหนดให้มี Enforce Referential Integrity, Cascade Update Related Fields และ Cascade Delete Related Fields ด้วย  คุณสมบัติของ Enforce Referential Integrity จะทำให้เมื่อมีการเพิ่มเรคอร์ด เราใส่ข้อมูลลงในฟิลด์ของเทเบิลแรก และเว้นข้อมูลในฟิลด์ของเทเบิลที่ 2 ก็ได้ ก็จะไม่มีเรคอร์ดปรากฏในเทเบิลที่ 2   แต่ถ้าเราใส่ข้อมูลในฟิลด์ของเทเบิลที่ 2 เราจะต้องใส่ข้อมูลอะไรลงในฟิลด์ของเทเบิลแรกด้วย  ส่วนคุณสมบัติ Cascade Update จะทำให้เมื่อมีการแก้ไขค่าในฟิลด์ Primary Key ของเทเบิลแรกแล้ว ค่านั้นจะไปแก้ไขในฟิลด์ Primary Key ของเทเบิลที่ 2 ให้โดยอัตโนมัติ  สุดท้ายคือคุณสมบัติ Cascade Delete จะทำให้เมื่อเราลบเรคอร์ดในเทเบิลแรกแล้ว เรคอร์ดในเทเบิลที่ 2 ที่มีค่า Primary Key เดียวกันก็จะถูกลบโดยอัตโนมัติเช่นกัน

ต่อมาให้สร้าง Query ใน Design View และลากทั้ง 2 เทเบิลนี้มาใส่ (มันจะแสดงเส้น Relationships ออกมาให้ด้วย) แล้วเลือกฟิลด์ที่เป็น * จากทั้ง 2 เทเบิลมาใส่ในคิวรี่

คุณสามารถนำเอา Query ตัวนี้ไปเป็น Record Source ของฟอร์มหรือรายงานที่ต้องการได้

อย่างไรก็ตาม ลองพิจารณาดูอีกทีว่าเราได้ออกแบบเทเบิลให้เป็นไปตามหลักการ Normalization แล้วหรือยัง ทำไมจำนวนฟิลด์ถึงมีมากขนาดนั้น !!!

6
เอาอย่างง่ายๆคือ

    DoCmd.SetWarnings False
    DoCmd.RunSQL  "Update tbl_farm set member_id = Forms![ชื่อฟอร์ม]!cbo_TF_TO where member_id = Forms![ชื่อฟอร์ม]!cbo_TF_From"
    DoCmd.SetWarnings True

8
น่าจะเป็น VB.Net ใช่ไหม ผมไม่เคยใช้มาก่อนเลย ทั้งหมดในหน้าจอคืออะไรผมไม่รู้เลย เห็นแต่ตรงนี้ที่มันบอกว่า path ที่อยู่ของไฟล์ Database.accdb ไม่ถูกต้อง อาจเป็นเพราะสาเหตุนี้ก็ได้ครับ ก็ลองแก้ไข path ให้ถูกต้อง


9
คิวรี่ไม่ทำงาน แล้วมี error อะไรแสดงออกมาหรือไม่ และอาจทดสอบโดยการสร้างโปรแกรมเล็กๆ พอกดปุ่มบนฟอร์มก็รันคิวรี่ที่อัพเดตค่าอะไรบางค่าลงฐานข้อมูลทดลองไปเลย ดูว่าทำได้หรือไม่

อีกอย่างคือเมื่อปลายปีที่แล้ว ตัวอัพเดตของ Office ก่อให้เกิดปัญหากับตัวคิวรี่ ตอนนี้ทางไมโครซอฟ์ทได้มีตัวแก้ไขออกมาให้แล้ว ลองอ่านที่นี่ดูครับ https://accessexperts.com/blog/2019/11/13/critical-office-update-breaks-access-query-is-corrupt/?fbclid=IwAR1gvYE82pQJmKUW9HFjBbhrYAnBMDmGEmJ3XI-GdEB09wk0vyvS9hTSEyE link

11
นี่มันข้อสอบไม่ใช่หรือ !

12
ขอเพิ่มเติมจาก อ. OddyWriter หน่อยครับ

อ้างถึง
แนวทางการออกแบบ Databased ที่ผมทำมานี้ เหมาะสมแล้วหรือไม่? ถ้าไม่ ผมควรจะออกแบบอย่างไรเพื่อให้ได้ตามโจทย์ที่ผมต้องการ?
เท่าที่เห็นตอนนี้
- ในระบบมีเทเบิลที่มี 2 ฟิลด์เยอะทีเดียว บางตัวจำเป็นหรือไม่ อย่างเช่นเทเบิล tblBlood ถ้าเป็นผม ผมจะกำหนดตัวเลือกลงในส่วนของ Lookup tab ของฟิลด์ tblContractor.BloodID ไปเลยว่ามีอะไรให้เลือกบ้าง เพราะ 1)กรุ๊ปเลือดตายตัวอยู่แล้ว มีไม่กี่กรุ๊ป (A, A+, A-, ...)  2)ระบบของเราไม่มีความจำเป็นต้องเก็บรายละเอียดอะไรของกรุ๊ปเลือดนั้นอีก เช่น กรุ๊ปนั้นมีแอนติเจ้น A,B,D หรือเปล่า การแยกเทเบิลออกไปในกรณีนี้ เป็นภาระแก่ระบบที่ต้องมาลิงค์ไปยังเทเบิล tblBlood อีกต่างหาก 3)ถ้าตั้งค่า BloodID เป็นอะไรที่ไม่สื่อความหมาย เช่น ตัวเลข ดังนั้นเวลาเปิดดูเทเบิล tblContractor ก็จะต้องมานั่งนึกอีกว่ามันคือเลือดกรุ๊ปอะไรกันแน่ ส่วนเทเบิลอื่นเช่น tblPlant คุณคิดว่าโรงงานจะสร้างเพิ่ม/เปลี่ยนแปลงบ่อยขนาดไหน ถ้าไม่ เมื่อไหร่ที่มีก็ค่อยมาเพิ่มใน Lookup tab ก็ได้
- เข้าใจว่าฟิลด์ xxxID ในทุกเทเบิลจะเป็น Primary Key แต่เราใช้ฟิลด์อื่นๆที่เหมาะสมกว่าเป็น Primary Key ก็ดีกว่าเพราะมัน unique คือมีค่าเดียวไม่ซ้ำกันอยู่แล้ว เช่น tblContractor เราเป็นบุคคลทั้งหมด เราก็ใช้เลขประจำตัวประชาชน (เข้าใจว่าคือฟิลด์ NationalID) มาใช้แทน
- ในความสัมพันธ์ระหว่างเทเบิล (Database Tools - Relationships) ดูความเหมาะสมว่าควรกำหนด Referential Integrity, Cascade Update, Cascade Delete ด้วยหรือไม่  (ส่วนมากผมกำหนด Referential Integrity)

อ้างถึง
Subform โดยให้เป็น Unbound SubForm
- ไม่รู้ว่าทำไมกำหนดเป็น Unbound  ถ้าจะเป็น Unbound ซึ่งเราต้องควบคุมการเขียนลงเทเบิลอื่นๆอีกที ก็ย้ายเท็กซ์บ็อกซ์และคอนโทรลต่างๆใน Unbound SubForm มาไว้บน MainForm แล้วตีกรอบเพื่อแสดงเป็นนัยว่าเป็นข้อมูลที่แยกต่างหากจาก Session ไปเลยน่าจะดูเรียบง่ายกว่า หรือจะนำมาใส่ใน Tab control บน MainForm อีกที ก็สื่อเป็นหมวดหมู่ดี

อ้างถึง
ซึ่งผมเขียน Expression ที่ txtWorkID โดยเมื่อ Dropdown เลือก NationalID เมื่อไหร่ ระบบจะไปดึง Last WorkID ของพนง.คนนั้น ๆ มาจากtblWork(Transaction Table) มาโชว์ / เกิด Error ใน Subform
- ต้องเอาโค้ดที่ทำการดึงและแปะลงฟิลด์ที่เกิด #Error นั้นมาดูครับ

อ้างถึง
การทำแบบฟอร์มเพื่อคีย์หลักสูตรที่แต่ละตำแหน่งต้องอบรมให้ครบตามกฎหมาย
- ก็ต้องมีเทเบิลหลักสูตร (tbSubject หรือเปล่า ?) ,เทเบิลตำแหน่ง (อันนี้ผมไม่รู้เทเบิลไหน สมมุติชื่อ tbP หรือเป็นแค่ฟิลด์ในเทเบิล tbWork ? สมมุติชื่อฟิลด์ F) และสร้างเทเบิลหลักสูตรที่ต้องอบรม (สมมุติชื่อ tbC) ที่มีทั้งฟิลด์ Primary Key ของเทเบิลหลักสูตรและ Primary Key ของเทเบิลตำแหน่ง(หรือแค่ฟิลด์ F ถ้าคุณไม่ได้มีเทเบิลตำแหน่งแยกออกมาต่างหาก) มานำมาตั้งเป็น Primary Key ของ tbC ดังนั้นคุณก็สร้างฟอร์มที่มี Mainform เป็น tbP และมี Subform เป็น tbC เพื่อป้อนหลักสูตรที่ต้องอบรมตามกฎหมายได้แล้ว

หมายเหตุ : Database ไม่ต้องใส่ d ต่อท้ายครับ

13
(ข้างล่างทั้งหมดนี้ ทำใน main report เท่านั้น)
- ใส่ Text Box control ตัวนึงไว้ที่ Page Header section หรือในตำแหน่งล่างแถบ Detail section ก็ได้ และกำหนด Control Source เป็น  =Pages (มีเครื่องหมายเท่ากับด้วย)
- ใส่ Page Break control สมมุติชื่อ PageBreak1 ไว้เหนือตำแหน่ง "2. แผนการผลิต"
- ใส่โค้ดนี้ไว้ใน Format event procedure ของ Detail section
    Me.PageBreak1.Visible = (Pages > 1)

14
ห้องสนทนาทั่วไป / : Linkไฟล์ PDF ในFolder
« เมื่อ: 04 ม.ค. 63 , 19:21:05 »
การจะแสดงข้อมูลในไฟล์ประเภทต่างๆ เช่น รูป, เสียง, ตารางเอ็กซ์เซล, เอกสารเวิร์ด, PDF, ฯลฯ บนฟอร์มหรือรายงานของ Access ได้ จะต้องหาตัว ActiveX Control ที่ใส่ลงฟอร์มหรือรายงานและสามารถอ่านไฟล์ประเภทนั้นได้ แต่เกรงว่าสำหรับ PDF จะไม่มีของฟรีครับ หรือจะลองไปหาในกูเกิลด้วยคำว่า Free ActiveX Pdf Reader Viewer ก็ได้ครับ สมมุติว่าได้แล้ว ฟิลด์ที่เก็บก็ต้องเปลี่ยนประเภทจาก Attachment เป็น OLE Object ด้วย

แต่ยังไงก็ตาม ปกติเราไม่เก็บเนื้อไฟล์ลงในฟิลด์ของ Access เพราะว่าไฟล์ .accdb, .mdb จะโตขึ้นเร็วมากและมันมีขนาดใหญ่สุดได้เพียงแค่ 2GB เท่านั้น ถ้าใช้งานจริง ใช้ๆไปแล้วจะช้าลงๆเรื่อยๆครับ ปกติที่ทำก็คือเราจะเก็บเฉพาะไฟล์พาธเอาไว้ในฟิลด์เท่านั้น เมื่อจะเปิดเอกสารที่อยู่ตามพาธนั้น ก็แค่สั่ง Followhyperlink เท่านั้น https://www.thai-access.com/topic_post.asp?CategoryID=1&TopicID=198 ส่วนการแสดงภาพเอกสารบนฟอร์ม ก็พอจะเลี่ยงๆได้คือ ต้องพิมพ์หน้าแรกของเอกสารเก็บเป็นรูปภาพด้วย เพราะ Access มี Image Control ที่สามารถแสดงรูปภาพที่เราเก็บพาธไฟล์รูปภาพเอาไว้ในฟิลด์ได้ด้วย แค่ใส่ชื่อฟิลด์ไว้ใน Control Source property ของ Image Control เท่านั้นเองครับ

15
ถ้าให้เห็นด้วยว่าใครตอบสุดท้ายก็จะดีครับ จะได้รู้ว่ากระทู้ที่เราตอบมีการเคลื่อนไหวหรือไม่

16
อ้างถึง
1.ใน Form ผมหาผลรวมของ ชุด1 ได้แล้ว แต่ผมรวมมันโดยใช้ text box แต่ไม่รู้ว่าค่าตัวนี้มันไปบันทึกไว้ที่ไหน
Textbox ที่ Control Source อ้างถึงแหล่งข้อมูลอื่นๆนอกจากฟิลด์ในเทเบิล(ไม่รวม Calculated Field) จะไม่สามารถแก้ไขอะไรได้ และไม่ได้มีการบันทึกไว้ที่ไหน เป็นเพียงการแสดงผลเท่านั้น

อ้างถึง
2. ที่report อยากให้มี drop down list ให้เลือกว่าเราจะเลือกตัวไหนมา report ต้องทำอย่างไรครับ
Report แสดงได้อย่างเดียว ไม่มีส่วนให้รับ input จากผู้ใช้ผ่านหน้าของ Report เอง ต้องไปใส่ Listbox/Combo Box ในหน้าฟอร์มอื่นๆก่อนอีกทีนึงหรือจะใส่เอาไว้ในหน้า FACADE INPUT DATA เลยก็ได้ แล้วเมื่อคลิกปุ่มพิมพ์ ก็ค่อยไปแสดงหน้า Report ให้ตรงตามเงื่อนไขที่ได้เลือกไว้ ถ้าใช้เป็นแมโครก็ใช้ OpenReport action แล้วใส่เงื่อนไขในบรรทัด Where Condition หรือถ้าเขียนเป็นโค้ด VBA ก็ใช้คำสั่ง
โค๊ด: [Select]
DoCmd.OpenReport "ชื่อรายงาน", acViewPrint (เพื่อพิมพ์เลย หรือ acViewPreview เพื่อดูก่อนพิมพ์), , "เงื่อนไข"
สำหรับเงื่อนไข ก็จะมีรูปแบบเป็น expression เช่น "ฟิลด์ = Forms![ชื่อฟอร์ม]![ชื่อ Listbox/Combo Box]" เป็นต้น
หรือลองค้นกระทู้เก่าด้วยคำว่า OpenReport ก็จะเห็นเยอะแยะครับ

อ้างถึง
1.table คือสำหรับสร้างฐานข้อมูล input data
ใช่

อ้างถึง
2. qry เอา input มาจัดเรียงและสร้างการคำนวนผลของ input data เพื่อทำ form
เราสามารถเอาเทเบิลต่างๆที่มีความสัมพันธ์กัน มาเชื่อมโยงกัน(เหมือน Lookup ไปชีทอื่นใน Excel) แล้วเลือกเอาเฉพาะฟิลด์ที่เราสนใจจากเทเบิลเหล่านั้นออกมา หรือเอามาคำนวน แล้วจะเอาคิวรี่มาเป็นแหล่งข้อมูลของ Form, Report, Recordset หรือเอามาแสดงด้วยตัวมันเองเลยก็ได้

อ้างถึง
3. form เพื่อให้หน้าตาในการ input data ง่ายและสะดวกในการใช้งาน
จะว่าอย่างงั้นก็ได้ครับ อีกอย่างคือเพื่อไม่ให้ผู้ใช้เข้าไปถึงแหล่งข้อมูลทั้งหมดเอง

อ้างถึง
4. report เพื่อแสดงรายการที่ต้องให้แสดงและ print
ใช่ครับ

เพิ่มเติม : Access เป็นโปรแกรมประเภท ระบบจัดการฐานข้อมูล (Database Management System, DBMS) แบบคุณสมบัติปานกลาง หลักการที่สำคัญของ DBMS ก็คือจะมีคุณสมบัติ ACID ลองอ่าน https://www.thai-access.com/topic_post.asp?CategoryID=1&TopicID=272

หน้า: [1] 2 3 4 ... 25