แสดงกระทู้

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 ... 7 8 9 [10] 11 12 13 ... 19
163
คุณจะดึงฟิลด์ Attachment มาจากคิวรี่แล้วมากำหนดให้ Attachment Control โดยตรงอย่างนี้ไม่ได้  แต่เราสามารถเอามาเป็น Control Source ของ  Attachment Control ได้ ดังนั้นเราจะสร้าง Attachment Control ตัวนึง (ชื่อว่า A) ใส่ลงฟอร์มเปล่า (ชื่อว่าฟอร์ม F) แล้วเอา F มาใส่เป็น Sub Form control (ชื่อ SF) ใน ฟอร์มการยืมอีกที ทีนี้เมื่อใดที่มีการเลือก Asset เราก็จะสร้าง Record Source ของ SF เป็น SQL SELECT statement ที่ดึงเอาเฉพาะฟิลด์ Attachment ที่เก็บรูปภาพตาม Asset_ID ที่เลือก  ดังนั้นภาพก็จะแสดงออกมา เท่านี้เองครับ

โค้ดให้ใส่ไว้ใน Private Sub cbo_Loanasset_AfterUpdate() , ใน Private Sub Form_Current() และใน Private Sub Form_Undo(Cancel As Integer) ด้วย
โค๊ด: [Select]
    If IsNull(Me.cbo_Loanasset) Then
        Me.SF.Form.RecordSource = ""
    Else
        Me.SF.Form.RecordSource = "select Asset_Photo from tb_Asset where Asset_ID = " & Cstr(Me.cbo_Loanasset)
    End If

นอกจากนี้ให้กำหนด property เหล่านี้เอาไว้ด้วย

สำหรับ A
Control Source เป็น Asset_Photo
Enabled   No

สำหรับ F
Record Selectors   No
Naviagtion Buttons   No
Dividing Lines      No
Scroll Bars         Neither
Recordset Type      Snapshot

ที่เหลือก็ปรับขนาดกรอบรูปเท่านั้นครับ
โพสต์นี้ได้รับคำขอบคุณจาก: Tonwrp

164
เลือก Data Entry property ของฟอร์มเป็น Yes เท่านี้เองครับ
โพสต์นี้ได้รับคำขอบคุณจาก: Tonwrp

165
แย่แล้วผม ทำไมผิดอย่างนี้    DoCmd.SetWarnings False หรือ True ไม่ต้องมีเครื่องหมาย = ครับ
โพสต์นี้ได้รับคำขอบคุณจาก: Tonwrp

166
ถ้าได้ก็อัพโหลดโปรแกรมมาครับ หรือไม่ก็ค่อยๆ comment หรือตัดไปทีละบรรทัด ดูว่าเมื่อไหร่ไม่มี error ก็แปลว่าบรรทัดนั้นเป็นปัญหาครับ
โพสต์นี้ได้รับคำขอบคุณจาก: Tonwrp

167
ให้ลองเปลี่ยนชื่อ Loan_No, Loan_Date, Employee_ID, Asset_ID ไปเป็น  Me.ชื่อเท็กซ์บ็อกซ์หรือคอมโบบ็อกส์  ที่ตรงกันบนฟอร์มดูครับ  ถ้ายังไม่ได้อีก ก็ให้ลอง Compact and Repair Database ครับ
โพสต์นี้ได้รับคำขอบคุณจาก: Tonwrp

168
อ้างถึง
ขึ้นว่า Invalid SQL Statement ครับ
แปลว่า SELECT statement นั้นมีอะไรผิดแล้ว เช็คดีๆครับว่าชื่อฟิลด์ ชื่อเทเบิล ถูกต้องหรือไม่

อ้างถึง
ใน Tb_Assets นั้นตรงฟิลด์ที่เป็น Yes/No มันเอาติ๊กออกหมดเลยครับกลายเป็น No หมดเลย
ในคำสั่ง DoCmd.RunSQL "UPDATE ... เช็คชื่อฟิลด์ เทเบิล และคอมโบบ็อกส์ว่าถูกต้องหรือไม่

อ้างถึง
มันแจ้งว่าเกิด Debug ใน Code
มันบอกว่า error อะไรครับ เอาข้อความมาแสดงหน่อย หรือว่าคุณแบ่งโค้ดเป็น 2 บรรทัด  ถ้าใช่ ให้แก้ไขให้อยู่ในบรรทัดเดียวกันนะครับ

สุดท้าย ให้คลิกที่เมนู Debug และ Compile ดูว่ามีข้อผิดพลาดอะไรแสดงออกมาหรือไม่

ปล.คงอีกหลายชั่วโมงผมถึงเข้ามาตอบอีกทีครับ
โพสต์นี้ได้รับคำขอบคุณจาก: Tonwrp

169
อ้างถึง
คราวนี้เป็น Status เป็น No หมดทุกตัวเลยครับอาจารย์
หมายถึงคอมโบบ็อกส์แสดงพวกที่เป็น No หมด หรือว่ายังไง

เอาโค้ดที่เขียนมาให้ดูอีกทีครับ

และลองทดสอบโดยการก็อปปี้ข้อความในส่วนสีแดง (จากโค้ดคุณเองนะ ไม่ใช่ก็อปจากคำตอบนี้) แล้วไปเปิด Query ใหม่สักตัว เลือกแสดงเป็น SQL View  แปะข้อความที่ก็อปปี้ลงไป  แล้วเปิดเป็น Datasheet View ดูว่าผลเป็นอย่างไร
 
Me.Asset_ID.RowSource = "  SELECT Asset_ID FROM Tb_Assets WHERE ASSET_Status = YES  "
โพสต์นี้ได้รับคำขอบคุณจาก: Tonwrp

170
Me.Asset_ID.RowSource = "SELECT Asset_ID, FROM    <---- มี , เกินมาครับ เอาออกด้วย

CSrt(Me.Asset_ID)  ผิดนะครับ ต้องเป็น CStr(Me.Asset_ID)

Me.Asset_ID.RowSource เปลี่ยนเป็น Me.cboAsset_ID.RowSource

ทำไมชื่อ procedure เป็น Form_frm_Loan_Current ปกติมันจะเป็น Form_Current เท่านั้น ???
โพสต์นี้ได้รับคำขอบคุณจาก: Tonwrp

171
- Asset_ID มี Data Type เป็นอะไรครับ แลัวเอาโค้ดที่เขียนใน Form_Current event procedure มาแสดงหน่อยครับ
- เมื่อดูผ่านเทเบิล Asset โดยตรง เห็นมีเรคอร์ดที่ Status เป็น No แน่ๆแล้วใช่ไหมครับ

ส่วนการยกเลิกแสดงข้อความเตือน ให้สั่ง DoCmd.SetWarnings = False/True คร่อมเอาไว้ครับ
DoCmd.SetWarnings = False
DoCmd.RunSQL "UPDATE Asset ....
DoCmd.SetWarnings = True

โพสต์นี้ได้รับคำขอบคุณจาก: Tonwrp

172
โค๊ด: [Select]
Private Sub bt_SaveLoan_Click()
  Dim SavRec    As Boolean
 
  If IsNull(Loan_No) Then
    MsgBox ("Please Put Loan No")
  ElseIf IsNull(Loan_Date) Then
    MsgBox ("Please Put Loan Date")
  ElseIf IsNull(Employee_ID) Then
    MsgBox ("Please Put Employee Name")
  Else
    DoCmd.RunCommand (acCmdSaveRecord)
    DoCmd.RunSQL "UPDATE Asset SET Status = FALSE WHERE Asset_ID = " & CStr(Me.Asset_ID)
    SavRec = True
  End If
End Sub

ก็แค่เพิ่มมาบรรทัดเดียวเอง เป็นการสั่ง SQL statement ให้ทำงาน  (จริงๆการทำอะไรกับข้อมูลในเทเบิล สามารถทำได้หลายวิธี แต่เพื่อให้ง่าย ก็เลยเลือกใช้ .RunSQL นี้ก่อนครับ)  แต่ถ้าฟิลด์ Asset_ID ในเทเบิล Loan มีประเภทข้อมูลเป็น Text ให้เปลี่ยนข้างท้ายของบรรทัดเป็น   Asset_ID = '" & Me.Asset_ID & "'"   และถ้าฟิลด์สถานะของ Asset ไม่ใช่ชื่อ Status ก็เปลี่ยนให้ถูกต้องด้วยนะครับ

อีกอย่างที่สังเกตเห็นก็คือ ลืมเช็คว่าผู้ใช้ได้เลือก Asset แล้วหรือเปล่า

เพิ่งคิดได้ว่าถ้าคุณเลื่อนกลับไปเรคอร์ดยืมเก่าๆที่ยังไม่คืน คุณอาจจะมองไม่เห็น Asset บนฟอร์ม เพราะก่อนหน้านี้ คอมโบบ็อกซ์อาจถูกกำหนดให้แสดงเฉพาะตัวที่ยังมีให้ยืมได้เท่านั้น ดังนั้นควรเปลี่ยนไปใช้ Form Current เพื่อกำหนด Row Source ให้กับคอมโบบ็อกซ์ โดยต้องรวมเอา Asset ของการยืมนั้นๆเข้ามารวมกับ Asset ที่ยังมีให้ยืมด้วย  แต่ถ้าเป็นการยืมรายการใหม่ ก็ให้มีเฉพาะ Asset ที่ยังมีให้ยืมเท่านั้น โค้ดก็จะมีลักษณะเป็น

โค๊ด: [Select]
Private Sub Form_Current()
    If Me.NewRecord Then
        Me.Asset_ID.RowSource = "SELECt ฟิลด์ต่างๆ FROM Asset WHERE Status = True"
    Else
        Me.Asset_ID.RowSource = "SELECt ฟิลด์ต่างๆ FROM Asset WHERE Asset_ID = " & CStr(Me.Asset_ID) & " OR Status = True"
    End If
End Sub
โพสต์นี้ได้รับคำขอบคุณจาก: Tonwrp

173
1. หน้าฟอร์มที่บันทักการยืมนั้น ตกลงมี sub form หรือไม่
2. โค้ดที่มีใน OnClick ของปุ่ม Save ตอนนี้มีอะไรอยู่บ้าง แล้วออกแบบไว้ว่าจะให้มันทำอะไรบ้าง
3. ปุ่ม Save อยู่บน main form หรือ sub form
4. ถ้าไม่กดปุ่ม Save  แล้วรายการที่ป้อนไปจะเป็นยังไง ?  บันทึกไม่ได้ หรือบันทึกได้แต่ถือว่าไม่เอาไปใช้อ้างอิงในระบบ
โพสต์นี้ได้รับคำขอบคุณจาก: Tonwrp

174
เปลี่ยนจาก FileSystemObject.CopyFile เป็น CreateObject("Scripting.filesystemobject").CopyFile ครับ
โพสต์นี้ได้รับคำขอบคุณจาก: Un, Phonemania

175
โทษที  คำสั่ง Name ใช้สำหรับเปลี่ยนชื่อไฟล์เท่านั้น ถ้าจะก็อปปี้ใหใช้ FileSystemObject.CopyFile "ไดร์ฟต้นทาง:\พาร์ธต้นทาง\......\ชื่อไฟล์ต้นทาง.jpg", "ไดร์ฟปลายทาง:\พาร์ธปลายทาง\.......\ชื่อไฟล์ปลายทาง.jpg"
โพสต์นี้ได้รับคำขอบคุณจาก: Un

176
สามารถทำได้ครับ โดยใน Row Source property ก็เขียนคำสั่ง SQL SELECT statement เพื่อคิวรี่เอามาเฉพาะที่ของยังไม่ได้ยืมหรือคืนของมาแล้ว ทีนี้ก็ขึ้นอยู่กับการออกแบบระบบของเราเองว่า จะรู้ได้ยังไงว่า คืนของมาแล้ว อย่างวิธีการที่คุณบอกมาก็เป็นวิธีนึง หรืออาจจะไม่ต้องสร้างฟิลด์ที่ว่านั้น ถ้าคิวรี่จากเทเบิลยืม/คืนมาเปรียบเทียบกันโดยตรงได้เลย (กรณีที่การหาสถานะนั้นซับซ้อนเกินกว่าเขียนทั้งหมดใน SQL เราสามารถเขียนโค้ดเป็น Public Function ใน Module เพื่อหาสถานะ แล้วให้ SQL ก็เรียกใช้ฟังก์ชั่นนี้ก็ได้)

แต่ไม่ว่าจะวิธีไหน เราต้องสั่ง ชื่อคอมโบบ็อกส์.Requery เพื่อให้ SQL ที่เขียนไว้นั้นทำงานอ่านสถานะตอนนั้นมาใหม่ ถ้าชัวร์สุดก็สั่งใน On Enter event ของคอมโบบ็อกส์ครับ
โพสต์นี้ได้รับคำขอบคุณจาก: Tonwrp

177
แต่ละเท็กซ์ไฟล์มีจำนวนฟิลด์/ชื่อฟิลด์/ประเภทข้อมูลเหมือนกันไหม ถ้าเหมือนกันหมด ก็อปปี้เท็กซ์ไฟล์เป็นไฟล์ชั่วคราว(สมมุติชื่อ T.txt) เทเบิลก็ให้ลิงค์ไปยัง T.txt   พอจะเปลี่ยนชื่อ ก็ลบ T.txt แล้วก็อปปี้ไฟล์อื่นมาเป็น T.txt แทน และ Refresh Link ตัวเทเบิลอีกครั้ง ผมว่าจะง่ายกว่า โค้ดก็คือ

Kill "เท็กซ์ไฟล์ชั่วคราว"
Name "เท็กซ์ไฟล์ใหม่", "เท็กซ์ไฟล์ชั่วคราว"
CreateObject("Scripting.filesystemobject").CopyFile "เท็กซ์ไฟล์ใหม่", "เท็กซ์ไฟล์ชั่วคราว"
CurrentDB.TableDefs("ชื่อเทเบิล").RefreshLink
โพสต์นี้ได้รับคำขอบคุณจาก: Un, Phonemania

178
ข้อความบอกเป็นนัยว่า รหัสแผนกที่เลือก ไม่มีอยู่ในเทเบิล dDepartment ครับ เช็คดีๆว่าป้อนรหัสแผนกถูกหรือไม่
โพสต์นี้ได้รับคำขอบคุณจาก: oraaoi

179
ต้องมีทั้ง 2 เทเบิลครับ เพราะมันคือฟิลด์ที่ไว้เชื่อมความสัมพันธ์กันของทั้ง 2 เทเบิล ไม่อย่างนั้น เวลาเราอ่านเรคอร์ดจาก LoanedItems เราจะไม่สามารถโยงไปหาข้อมูลของการยืมเดียวกันนี้ในเทเบิล Loan ได้เลย

จากวิธีที่ผมบอกไป เราไม่ได้สร้างฟอร์มจากคิวรี่ครับ แต่ละฟอร์มสร้างจากแต่ละเทเบิลครับ 

ส่วนคิวรี่ ผมเขียนเอาไว้เพื่ออธิบายถึงประโยชน์ของการสร้าง Lookup ในฟิลด์ต่างๆ เพื่อที่เราจะได้ไม่ต้องดึงเอาเทเบิล Employees, Customers และ Asset เข้ามาในคิวรี่ด้วย ทำให้ดูสะอาดตา ไม่รกรุงรัง  ยกเว้นว่าเราต้องการฟิลด์อื่นๆที่นอกเหนือไปจาก  _Name และ _Description จาก 3 เทเบิลที่ว่านี้ ซึ่งแน่นอนว่าเราต้องดึงเอาเทเบิลนั้นๆมาใส่ในคิวรี่ด้วยครับ
โพสต์นี้ได้รับคำขอบคุณจาก: Tonwrp, Suparak Kunkeaw

180
ลองนึกถึงใบเสร็จเวลาเราไปซื้อของในห้าง ที่หัวกระดาษเขาจะพิมพ์ว่าแคชเชียร์คือใคร และเราซึ่งเป็นลูกค้าเป็นใคร ส่วนกลางกระดาษก็จะแสดงรายละเอียดสินค้าว่าเราซื้ออะไรบ้าง ซึ่งรองรับได้หลายๆรายการ  ถ้าคุณต้องการลักษณะการเก็บแบบนี้ แปลว่านอกจากเทเบิล Loan ซึ่งเปรียบได้กับหัวกระดาษแล้ว ก็จะต้องมีเทเบิล LoanedItems ซึ่งเป็นรายละเอียดของที่ยืมเพิ่มเติมอีกครับ และอย่างน้อยก็จะมีฟิลด์ Loan_No (PK), Asset_ID(PK) ที่ย้ายมาจากเทเบิล Loan เอามาใส่ไว้ที่นี่แทน และจำนวนที่ยืมด้วยครับ และเราจะสร้างความสัมพันธ์ (Table Relationships) ระหว่างทั้ง 2 เทเบิลไว้ด้วย   (ส่วนนี้หาวิธีทำใน Youtube ด้วยคำว่า  microsoft access table relationships)

สำหรับการบันทึก ก็สร้างฟอร์มสำหรับเทเบิล Loan และ LoanedItems แล้วเราจะเอาฟอร์มของ LoanedItems มาใส่ในฟอร์มของ Loan อีกที (เราจะเรียกฟอร์มของ Loan ว่าเป็น main form และ LoanedItems ว่าเป็น sub form) เป็นการเชื่อม 2 ฟอร์มเข้าด้วยกันด้วย Loan_No ทีนี้ก็จะได้หน้าฟอร์มที่เหมือนมีหัวกระดาษและรายละเอียดรายการยืม/คืนอยู่ภายใน  (ส่วนนี้หาวิธีทำใน Youtube ด้วยคำว่า  microsoft access subform)

และเพื่อให้การแสดงดูเข้าใจมากขึ้น เราจะกำหนดคุณสมบัติต่างๆในแทป Lookup ของฟิลด์ Employee_ID, Customer_ID, Asset_ID ให้เชื่อมโยงไปยังเทเบิล Employees, Customers และ Asset เพื่อที่ว่าระบบจะดึงเอา Employees_Name, Customer_Name และ Asset Description มาแสดงแทนที่จะแสดงเป็น ID ซึ่งอาจไม่สื่อความหมายให้ผู้ใช้ได้เข้าใจอย่างชัดเจนสักเท่าไหร่ ดังนั้นเมื่อถึงเวลาสร้างคิวรี่ที่มีเทเบิล Loan และ LoanedItems เชื่อมระหว่างกัน และเลือกฟิลด์ Employee_ID, Customer_ID, Asset_ID มาแสดง   Access ก็จะดึงเอา _Name และ _Description ของค่าเหล่านี้มาแสดงให้อย่างอัตโนมัติเช่นกัน (ส่วนนี้หาวิธีทำใน Youtube ด้วยคำว่า microsoft access table lookup field) แต่ถ้าหากเราไม่ได้สร้าง Lookup เอาไว้ในฟิลด์ข้างบน ตอนสร้างคิวรี่ เราก็ต้องดึงเอาเทเบิล Employees, Customers และ Asset เข้ามาในคิวรี่ด้วย แล้วสร้างความสัมพันธ์ในคิวรี่เองครับ
โพสต์นี้ได้รับคำขอบคุณจาก: Tonwrp

หน้า: 1 ... 7 8 9 [10] 11 12 13 ... 19