แสดงกระทู้

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 ... 8 9 10 [11] 12 13 14 ... 19
181
ผมคิดออกแต่วิธีทื่อๆตรงๆนะครับ ไม่เทคนิคอะไร ผมคิดว่าต้องทำการป้อนผ่านฟอร์มเท่านั้นเพราะจะต้องเขียนโค้ดใน Form_BeforeUpdate event เพื่อควบคุมและค้นหาเลขตัวต่อไปของ Autonumber ซึ่event นี้จะเกิดก่อนที่จะบันทึกเรคอร์ด สิ่งที่ต้องทำก็คือ

1. เปลี่ยนประเภทข้อมูลของฟิลด์ Autonumber (สมมุติว่าชื่อฟิลด์คือ A แล้วกัน) ให้เป็น Long Integer เพื่อโปรแกรมจะได้ควบคุมค่านี้เอง เราจะไม่ปล่อยให้ Access หาค่ามาใส่ให้อย่างแต่ก่อนอีกแล้ว และต้องกำหนด A ให้คุณสมบัติ Unique Index เป็น True ด้วย ถ้า A เป็น PrimaryKey อยู่แล้ว ก็จะเป็น Unique Index โดยอัตโนมัติ

2. เพิ่มฟิลด์อีกฟิลด์เพื่อบอกให้เรารู้ว่า นี่เป็นเรคอร์ดของกลุ่มเดียวกันใน 26 เรคอร์ด เรียกชื่อว่าฟิลด์ DT สำหรับใส่ TimeStamp ก็แล้วกัน  DT มีประเภทข้อมูลเป็น Date/Time  โปรแกรมจะใส่วันเวลาปัจจุบันลงไปใน DT ให้เรคอร์ดแรกของกลุ่ม  (#2.1) ส่วนเรคอร์ดอื่นๆ โปรแกรมจะก็อปปี้ค่า DT จากเรคอร์ดชุดสุดท้ายมาใส่ให้แทน (#2.2)  หมายเหตุ : ฟิลด์ DT ไม่จำเป็นต้องใส่ในฟอร์ม

3. ในฟอร์ม ถ้ามันเป็นเรคอร์ดแรกในชุดของ 26 เรคอร์ดชุดใหม่ โปรแกรมจะใช้ค่าในฟิลด์ A ที่คุณต้องป้อนในฟอร์ม (#3.1) นำมาเป็นค่าเริ่มต้น แต่ถ้าไม่ใช่เรคอร์ดแรก โปรแกรมจะไม่สนใจค่าที่คุณป้อน แต่จะหาค่าล่าสุดของ A ในกลุ่ม 26 เรคอร์ดสุดท้าย บวกด้วย 1 แล้วเอามาใส่ที่ฟิลด์ A แทน (#3.2)

4. ถ้าเกิดกรณีที่ป้อนค่า A ซ้ำ โปรแกรมจะให้ป้อนใหม่  (#4.1) ถ้ากรณีบวก 1 แล้วเจอค่าซ้ำกับเรคอร์ดเก่า  โปรแกรมจะบวก 1 เพิ่มเติมต่อไปเรื่อยๆจนกว่าจะไม่ซ้ำ (#4.2)

ไปเปลี่ยนชื่อฟิลด์ของเทเบิลและบนฟอร์มให้ตรงกับที่คุณมีด้วยครับ
โค๊ด: [Select]
Private Sub Form_BeforeUpdate(Cancel As Integer)

Const MaxRec = 26
Dim DB          As DAO.Database
Dim RS          As DAO.Recordset
Dim MaxDTStr    As String   ' วันเวลาล่าสุดของกลุ่มเรคอร์ด (แต่เป็น string เพื่อลดความยาวของโค้ด)
Dim MaxA        As Long     ' ค่าสูงสุดของ A ในกลุ่มเรคอร์ดล่าสุด
Dim NeedA       As Boolean  ' TRUE = ระบบต้องการค่า A บนฟอร์ม

    NeedA = False
   
    Set DB = CurrentDb
    Set RS = DB.OpenRecordset("select max(DT) as MaxDT from TB")
    If IsNull(RS!MaxDT) Then
        NeedA = True
    Else
        ' #2.2
        MaxDTStr = Format$(RS!MaxDT, "dd/mmm/yyyy hh:nn:ss")
        Set RS = DB.OpenRecordset("select count(*) as N from TB where DT = #" & MaxDTStr & "#")
        If RS!N = 0 Or RS!N >= MaxRec Then NeedA = True
    End If
   
    If NeedA Then
        ' #3.1
        If Nz(Me.A, 0) = 0 Then
            MsgBox "ป้อน A ด้วย"
            Me.A.SetFocus
            Cancel = True: Exit Sub
        End If
       
        If Not DB.OpenRecordset("select A from TB where A = " & CStr(Me.A)).EOF Then  ' #4.1
            MsgBox "A ซ้ำของเดิม"
            Me.A.SetFocus
            Cancel = True: Exit Sub
        End If
       
        Me.DT = Now()   ' #2.1
    Else
        ' #3.2
        Me.A = DB.OpenRecordset("select max(A) as MaxA from TB where DT = #" & MaxDTStr & "#")!MaxA
        Do
            Me.A = Me.A + 1
        Loop Until DB.OpenRecordset("select A from TB where A = " & CStr(Me.A)).EOF   ' #4.2
       
        Me.DT = CDate(MaxDTStr) ' #2.2
    End If
End Sub
โพสต์นี้ได้รับคำขอบคุณจาก: Nick_1234

182
ลองดูวิธีนี้ แต่ไม่แน่ใจว่าจะได้กับกรณีตารางหลุดนอกจอหรือเปล่านะครับ ให้คลิกที่ตารางอะไรก็ได้ในวินโดว์ Relationships แล้วกดปุ่ม TAB หรือ SHIFT-TAB เพื่อไปตารางถัดไปหรือก่อนหน้า ก็กดไปจนกว่าจะเจอตารางที่หลุดจากจอ แล้วก็ค่อยเอาเมาส์เลื่อนมันกลับเข้าไปอีกที

หรืออีกวิธีคือ คลิก Clear Layout ก็จะลบไดอะแกรมออกไป (ไม่ได้ลบ Relationship) แล้วคลิก All Relationships อีกที ทุกๆความสัมพันธ์ที่มีอยู่แล้วก็จะแสดงออกมาเป็นไดอะแกรมแบบทื่อๆ ซึ่งเราต้องมาจัดเรียงตำแหน่งทั้งหมดอีกที
โพสต์นี้ได้รับคำขอบคุณจาก: MiKu, O_o

183
แต่ถ้าเราเขียนคำสั่งที่จะทำ ให้อยู่ในบรรทัดเดียวกับ If ... Then ได้ เราก็ไม่ต้องมี End If ครับ เช่น

If A=1 Then B=2: C=3 Else B=4: C=5

หมายเหตุ เราใช้เครื่องหมาย : เพื่อคั่นแต่ละคำสั่งที่จะเขียนในบรรทัดเดียวกัน
โพสต์นี้ได้รับคำขอบคุณจาก: UnKnown, มาลี

184
If เงื่อนไข Then
   ทำคำสั่งเมื่อเงื่อนไขเป็นจริง
Else
   ทำคำสั่งเมื่อเงื่อนไขไม่เป็นจริง
End If


If เงื่อนไขที่1 Then
   ทำคำสั่งเมื่อเงื่อนไขที่1เป็นจริง
ElseIf เงื่อนไขที่ 2 Then
   ทำคำสั่งเมื่อเงื่อนไขที่1ไม่เป็นจริง แต่เงื่อนไขที่2เป็นจริง
ElseIf เงื่อนไขที่ 3 Then
   ทำคำสั่งเมื่อเงื่อนไขที่1และ2ไม่เป็นจริง แต่เงื่อนไขที่3เป็นจริง
ElseIf ...
   ...
Else
   ทำคำสั่งเมื่อเงื่อนไขทั้งหมดข้างบนไม่เป็นจริง
End If

การใช้ ElseIf ทำให้ลดรูปการเขียนคำสั่งด้วย If ... Then ... Else ซ้อนกันให้สั้นลงและอ่านง่ายขึ้นเท่านั้นเองครับ ไม่งั้นเราก็ต้องเขียนเป็น

If เงื่อนไขที่1 Then
   ทำคำสั่งเมื่อเงื่อนไขที่1เป็นจริง
Else
   If เงื่อนไขที่ 2 Then
      ทำคำสั่งเมื่อเงื่อนไขที่1ไม่เป็นจริง แต่เงื่อนไขที่2เป็นจริง
   Else
      If เงื่อนไขที่ 3 Then
         ทำคำสั่งเมื่อเงื่อนไขที่1และ2ไม่เป็นจริง แต่เงื่อนไขที่3เป็นจริง
      Else
         If ... Then
            ...
         Else
            ทำคำสั่งเมื่อเงื่อนไขทั้งหมดข้างบนไม่เป็นจริง
         End If
      End If
   End If
End If
โพสต์นี้ได้รับคำขอบคุณจาก: มาลี

185
ในภาษา VBA  เครื่องหมาย double quote เป็น string delimeter เปิด/ปิดสำหรับค่าคงที่ของข้อความ (ในนี้ผมจะใช้สีแดงแล้วกัน) เช่น ค่าคงที่ของข้อความ AB ก็จะต้องสร้างเป็น "AB"   แต่ถ้าค่าคงที่ของข้อความต้องมี double quote อยู่ภายในอยู่ด้วย เช่น A"B  เราต้องใช้ double quote 2 ตัว   VBA จะรู้ว่าจริงๆแล้ว นี่เป็นตัวอักษร double quote เพียงตัวเดียว ไม่ใช่ delimiter  ดังนั้นเราก็ต้องสร้างเป็น "A""B" 


ส่วน string delimeter ในภาษา SQL จะใช้ได้ทั้ง double quote และ single quote  ดังนั้นเมื่อต้องการค่าคงที่ของข้อความ SELECT * FROM Output WHERE [Type] like 'AB' ลงในตัวแปรชื่อ SQL เราก็จะสร้างคำสั่งเป็น SQL = "SELECT * FROM Output WHERE [Type] like 'ABC'" หรือถ้าเราใช้ double quote แทน single quote คำสั่งก็จะกลายเป็น SQL = "SELECT * FROM Output WHERE [Type] like ""ABC"""


ส่วน & คือ operator ที่ใช้เชื่อมข้อความ 2 ข้อความเข้าด้วยกัน เช่น "A" & "B" ก็จะได้ค่าคงที่ของข้อความเป็น AB หรือ "A" & """B""" ก็จะได้เป็น A"B"
โพสต์นี้ได้รับคำขอบคุณจาก: ปิ่นณรงค์, aek, apirak, mivien20

186
Object, Control, Textbox ต่างก็เป็น Data Type ใน Access   แต่ตัวแปรของ Object จะกว้างๆ เมื่อสร้างตัวแปรขึ้นมาด้วย Dim ตัวมันเองไม่มีคุณสมบัติอะไรอยู่เลย จนกว่ามันจะถูกกำหนดว่ามันคืออะไร เช่น จากรูป เมื่อกำหนดโดยคำสั่ง Set O = GetObject("C:\Data\DrugList.xls") กลไกของ Access ก็จะกำหนดให้ obj เป็น workbook ของ DrugList.xls ซึ่งหลังจากนี้เราก็สามารถเขียนโค้ดเพื่อเรียกใช้ property และ method ต่างๆที่ตัวโปรแกรม Excel มีให้กับ workbook ได้



แต่อย่างไรก็ตาม ถ้าเรากำลังพิมพ์คำสั่งในบรรทัดต่อๆไปว่า O. เราก็จะยังไม่เห็นว่ามันมี property หรือ method อะไรโผล่ขึ้นมาทั้งๆที่ได้กำหนดไปแล้ว ไม่เหมือนตัวแปร C ซึ่งเป็นตัวแปรประเภท Control ที่จะมี listbox แสดง property และ method ออกมาให้เห็น นั่นเพราะว่า Access จะรู้ว่า O คืออะไรก็ต่อเมื่อโค้ดได้ทำงานแล้ว แต่ขณะที่เรากำลังเขียนโค้ดอยู่ใน Editor นั้น โค้ดยังไม่ได้ทำงาน (ยกเว้นว่าเรากำลังอยู่ในโหมด Debug) ดังนั้น Access จะไม่มีทางรู้เลยว่ามันคืออะไร ก็เลยไม่สามารถแสดง listbox นั้นออกมาให้เราเห็น

Object ต่างกับ Control และ Textbox ตรงที่สองตัวหลังนั้นเป็น object ที่อยู่ในตัว Access เองอยู่แล้ว มันย่อมรู้ดีอยู่แล้วว่ามี property และ method อะไรอยู่บ้างโดยไม่ต้องไปผูกว่า Control หรือ Textbox นี้คือตัว "อะไร" บนฟอร์ม/รายงานตัวนั้น (แต่การที่รู้อยู่แล้ว ไม่ได้หมายความว่าเราจะเรียกใช้ property และ method ก่อนการผูกกับ "อะไร", ด้วยคำสั่ง Set, โดยไม่เกิด error message เพราะมันขึ้นกับว่า property และ method นั้นๆเกี่ยวข้องกับ "อะไร" ที่ Access ต้องรู้ว่ามีอยู่จริงๆก่อนหรือไม่ เช่น ชื่อของ Control หรือ Textbox เป็นต้น)

สรุปว่าเราจะใช้ Object ก็ต่อเมื่อเราต้องการผูก Object นั้นกับ "อะไร" นอกตัว Access เพื่อใช้งาน "อะไร" ตัวนั้น

ส่วน Control ก็คือองค์ประกอบต่างๆบนฟอร์ม/รายงาน เช่น Textbox, Line, Section เป็นต้น มันมี property และ method รวมๆที่องค์ประกอบต่างๆมีเหมือนๆกัน ซึ่งก็มีไม่เท่าไหร่

สุดท้าย Textbox ก็เป็น Object ที่เฉพาะเจาะจงสำหรับเท็กซ์บ็อกซ์ไปเลย มี property และ method เฉพาะ Textbox เท่านั้นครับ เราไม่ค่อยกำหนดตัวแปรของ Textbox เท่าไหร่ เพราะมักอ้างถึง Textbox นั้นได้โดยตรงอยู่แล้ว
โพสต์นี้ได้รับคำขอบคุณจาก: mbbrid, Krathok-man

187
การกำหนด Property ให้แก่คอนโทรลในบรรทัดของ Continuous Form จะมีผลกับคอนโทรลนั้นในทุกบรรทัดครับ แต่สำหรับการกำหนดคุณสมบัติในการแสดงบางอย่างเช่น สีพื้น, สีตัวอักษร. อักษรตัวหนา/ขีดเส้นใต้/ตัวเอียง, Enabled/Disabled สามารถใช้ Conditional Formatting ในการกำหนดเฉพาะคอนโทรลในบรรทัดนั้นๆตามเงื่อนไขให้เป็นไปอย่างอัตโนมัติได้ ดังนั้นอย่างแรกที่ต้องทำก็คือต้องหาก่อนว่าเงื่อนไขอะไรที่จะให้ Disabled   จากที่กำหนดมา ถ้าสมมุติว่าเมื่อเงื่อนไข cb_Status = "¨จบงาน" ก็ให้ Disabled ได้ ก็ให้ป้อน Conditional Formatting สำหรับคอนโทรลอื่นที่ต้องการเป็น (เช่น cb_DocEnvelope, txt_OrderID) [cb_Status] = "¨จบงาน" แล้วเลือกลักษณะคอนโทรลเป็น Disabled ครับ 



ส่วนโค้ดที่ให้มา ก็มีแค่นี้เท่านั้น

Private Sub Command27_Click()
    Me.txt_DateClose = Now()
    Me.cb_Status = "¨จบงาน"
End Sub
โพสต์นี้ได้รับคำขอบคุณจาก: sjs, Eik Q Sang

188
เพิ่มเติมหน่อยนะครับ ที่บอกไปครั้งก่อนว่า "ใน BeforeUpdate event จะไม่ยอมให้เราแก้ไขค่าในเท็กซ์บ็อกซ์ของตัวมันเอง" หมายถึงจะเกิด runtime error ขึ้น แต่ถ้าเราอยากข้าม error นี้ไป ก็ทำแบบเถื่อนๆคือใส่ On Error Resume Next ตามโค้ดที่แก้ไขข้างล่างนี้ก็ได้

Private Sub TxITEM_ฺBeforeUpdate(Cancel As Integer)
  If Me.TxItem.Text = "" Then
  ElseIf DCount("Item", "QrItem") > 0 Then
  Else
      MsgBox "Item ¹ÕéäÁèÁÕã¹ÃкºËÃ×ÍÂѧäÁèä´éà¾ÔèÁà¢éÒä»ã¹Ãкº", vbOKOnly, "Warning!"
      Cancel = True
      On Error Resume Next
      Me.TxItem.Text = ""

  End If
End Sub

หมายเหตุ : สังเกตให้ดีว่าเราต้องอ้าง TxtItem.Text นะครับ ไม่ใช่ TxtItem เฉยๆ
โพสต์นี้ได้รับคำขอบคุณจาก: sjs

189
ห้าม set focus กลับไปที่ตัวเองครับ การทดสอบว่าเงื่อนไขไหนไม่ผ่านและจะให้ยังคงอยู่ที่เท็กซ์บ็อกซ์เดิม เราต้องทำที่ BeforeUpdate event  และเราจะกำหนดพารามิเตอร์ Cancel เป็น True เพื่อให้ Access หยุดเพียงแค่ event นี้ ดังนั้นจึงไม่ต้องกำหนด .SetFocus เพิ่มเติม แต่เนื่องจากใน BeforeUpdate event จะไม่ยอมให้เราแก้ไขค่าในเท็กซ์บ็อกซ์ของตัวมันเองเช่นกัน จึงไม่สามารถกำหนดค่า Null กลับไปได้ วิธีที่พอทำได้คือ กำหนดให้ตัวอักษรทั้งหมดในเท็กซ์บ็อกซ์ถูกเลือก ดังนั้นผู้ใช้ก็สามารถป้อนค่าใหม่ทับของเดิมไปได้ทันทีครับ

โค้ดคุณก็จะมีแค่นี้ครับ

Private Sub TxITEM_ฺBeforeUpdate(Cancel As Integer)
  If Me.TxItem.Text = "" Then
  ElseIf DCount("Item", "QrItem") > 0 Then
  Else
      MsgBox "Item ¹ÕéäÁèÁÕã¹ÃкºËÃ×ÍÂѧäÁèä´éà¾ÔèÁà¢éÒä»ã¹Ãкº", vbOKOnly, "Warning!"
      Cancel = True
      Me.TxItem.SelStart = 0
      Me.TxItem.SelLength = Len(Me.TxItem.Text)
  End If
End Sub


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

190
ห้อง MS Access / : กำหนดช่วงวันที่
« เมื่อ: 24 พ.ค. 62 , 15:12:14 »
เดือน(วันที่ - 10) + 1 น่าจะให้ผลเดียวกันได้
โพสต์นี้ได้รับคำขอบคุณจาก: ปิ่นณรงค์

191
ผมไม่เคยใช้ MySQL นะครับ แต่ข้างล่างนี้เป็นหลักการ อาจพอช่วยได้

1. อาจเพราะไม่ได้สร้าง Primary Key ไว้ในเทเบิลบน MySQL

2. แต่ถ้าคิดว่าไม่ใช่ ก็ลองอ่าน https://www.thai-access.com/yeadram_view.php?topic_id=4308

3. ถ้าปัญหาเกิดตอนแก้ไขข้อมูลโดยตรงผ่านหน้าต่างเทเบิล, คิวรี่ หรือฟอร์ม ถ้าเขียนโค้ดจำลองการแก้ไขได้ ก็เขียนดูตามลิงค์ที่ให้ แต่ถ้าไม่เขียน ก็ต้องค้นกูเกิลดูว่าเราจะสร้างและดู MySQL Log File ได้อย่างไร (หาด้วยคำ MySQL Log File) เพราะ Log File ที่ MySQL เก็บไว้ จะเก็บสิ่งต่างๆที่เกิดขึ้นกับฐานข้อมูลของมันเอง ผมเชื่อว่ามันจะเก็บข้อความของปัญหาที่เกิดขึ้นนี้ด้วยว่าเกิดจากอะไรกันแน่

4. อีกอย่างคือ คุณอาจย้ายฐานข้อมูลจาก Access ไป MySQL ไม่ถูกต้องหรือไม่ครบถ้วน ขาดอะไรบางอย่างไป ผมค้นเจอมาว่า MySQL มีโปรแกรมชื่อ MySQL Workbench ซึ่งหน้าที่อันหนึ่งของมันก็คือทำการย้ายฐานข้อมูลจาก Access ไปให้ ลองอ่านดูครับ https://dev.mysql.com/doc/workbench/en/wb-migration-database-access.html
โพสต์นี้ได้รับคำขอบคุณจาก: chai, diehard4

192
เนื่องจาก Message Box ไม่อนุญาตให้โค้ดบรรทัดต่อไปทำงาน จนกว่าจะปิดกล่องข้อความที่แสดงไป ดังนั้นเราจึงต้องไปใช้อย่างอื่นทำหน้าที่แสดงข้อความแทน เช่น สร้างฟอร์มเพื่อทำหน้าที่เป็น Message Box, แสดงข้อความบน Textbox หรือ Command Button ภายในฟอร์มของตัวของเขาเองครับ ส่วนตัวผมเอง ผมหาพื้นที่สักส่วนนึงบนฟอร์มแล้วสร้าง Textbox เพื่อแสดงข้อความครับ ง่ายดี พอทำงานเสร็จ จะ Invisible มันไปด้วยก็ได้ หรือจะเคลียร์ข้อความใน Textbox ทิ้งก็ได้ ตย.เช่น

    Dim oFSO As Object
    Dim strDestination As String
    strDestination = "\\server\"
    DBEngine.Idle
    Set oFSO = CreateObject("Scripting.FileSystemObject")
   
    Me.[ชื่อ Textbox].Visible = True
    Me.[ชื่อ Textbox] = "ข้อความ"

    oFSO.CopyFile CurrentProject.Path & "Data1.accdb", strDestination   
    Set oFSO = Nothing
   
    Me.[ชื่อ Textbox].Visible = False
    Me.[ชื่อ Textbox] = ""

    MsgBox ("สำรองข้อมูลเสร็จแล้ว"), vbOKOnly + vbInformation, "Process Completed"

แต่ถ้าต้องการสร้างเป็นฟอร์มแทน Message Box ก็ไปสร้างฟอร์มโดยกำหนด Property ของฟอร์มเป็นค่าเหล่านี้
Pop up เป็น Yes
Scroll bars เป็น Neither
Record Selector เป็น No
Navigation Button เป็น No
Auto Resize เป็น Yes
Auto Center เป็น Yes
Border Style เป็น Thin หรือจะเป็น None ก็ได้ ลองดูเอาแบบที่ชอบครับ
Control เป็น None
แล้วก็สร้าง Textbox เพื่อไว้แสดงข้อความ พอจะใช้งาน ก็เพียงเปิดฟอร์มนี้ ใส่ข้อความลง Textbox แล้วปิดเมื่อทำงานเสร็จ เท่านี้เองครับ

โพสต์นี้ได้รับคำขอบคุณจาก: มาลี, diehard4, apirak

193
อ่านแล้ว งง คำถาม แต่ งง ไปอีก ทำไมอาจารย์เก่งจัง
เดาได้ด้วยว่าเค้าถามอะไร

:question: พูดแล้วผมเองก็อยากรู้เลยว่าคำถามไหน ยังพอจำโพสนั้นได้ไหมครับ
โพสต์นี้ได้รับคำขอบคุณจาก: apirak

194
คำถามจำนวนมาก ถามโดยแทบจะไม่อธิบายอะไรมาเลย ไม่ทราบคนถามจะรู้ไหมว่าคนอ่าน(เอาเป็นว่าอย่างน้อยก็ผมแล้วกัน)รู้สึกเหมือนโดนถามว่า "อยากได้จรวดไปดาวอังคาร ช่วยหน่อยครับ" จริงๆนะ แล้วจะให้ตอบอย่างไร ก็จะกลายเป็นต้องถามกลับไปว่า คุณได้ใช้อุปกรณ์อะไร ออกแบบอะไรยังไงไปแล้วบ้าง เอามาให้ดูหน่อย ซึ่งถ้าเป็นสมัยก่อน ผมก็จะพยายามถามกลับ แต่ยอมรับว่าเดี๋ยวนี้ โอกาสน้อยที่ผมจะถามกลับแล้ว ถ้าอ่านแล้วพบว่าข้อมูลที่ให้มาพร้อมคำถามของผู้โพสนั้นมีน้อยมาก ก็จะข้ามไปเลย หรือถามแล้วอ่านไม่เข้าใจเลย ผมก็ขอข้ามไปเหมือนกัน

ดังนั้น เพื่อเพิ่มความสมบูรณ์ของคำถาม มันก็มีหลายวิธี แต่หลายๆวิธีคงวุ่นวายไป ก็เลยคิดว่าก่อนระบบจะรับโพส อยากให้มี message box แสดงข้อความ "เขียนถามให้ผู้ตอบเข้าใจ..." ตามข้อความเตือนสีแดงๆที่อยู่บนหัวเพจอีกที และอาจมีข้อความอื่นเพิ่มเติมเพื่อเน้นว่าเขาแน่ใจไหมว่าได้อธิบายละเอียดแล้ว ถ้าเขาไม่ยืนยัน ก็ให้เขากลับไปแก้ข้อความ แต่ถ้าเขากดยืนยัน ก็ค่อยโพสจริงๆอีกที

ถามยาว โอกาสได้รับคำตอบเร็วมีสูง -- ถามสั้น โอกาสน้อยลง -- ถามสั้นมากๆ ยากที่จะมีโอกาส
โพสต์นี้ได้รับคำขอบคุณจาก: PookPuy, sjs, OddyWriter, diehard4, aek, apirak, PNR

195
ไม่เคยทำกับเรคอร์ดจำนวนมากอย่างนี้ ได้แค่ออกแนวคิดให้ แต่จะทำได้ผลจริงหรือไม่ อันนี้ไม่ทราบนะครับ วิธีคือต้องหาทางสร้างคิวรี่เพื่อให้ได้เรคอร์ดทีละล้านเรคอร์ดก่อน แล้วใช้ CopyFromRecordset method ของ Range object จาก Excel object https://docs.microsoft.com/en-us/office/vba/api/excel.range.copyfromrecordset เพื่อดึงข้อมูลจำนวนมากเข้าชีท แล้วก็เปิดชีทใหม่ วนทำกับคิวรี่ตัวต่อไปจนหมดครับ
โพสต์นี้ได้รับคำขอบคุณจาก: sjs

196
ต้องป้องกันตั้งแต่การป้อนครับ โดยกำหนดรูปแบบการป้อนใน Input Mask ของเท็กซ์บ็อกซ์นั้นๆ เช่น ป้อนได้ไม่เกิน 5 หลักและไม่มีทศนิยม ก็กำหนดเป็น 99,999  ส่วนการแสดง ปกติผมจะเลือก Format เป็น Standard และใส่จำนวนทศนิยมที่ต้องการในช่อง Decimal Places
โพสต์นี้ได้รับคำขอบคุณจาก: Kanxay Vnv

197
เชื่อว่า Price จริงๆแล้วไม่ได้เป็น 83 ครับ  น่าจะเป็น 82.50  แต่ format ของ Price บนหน้าฟอร์ม คงจะเป็นประเภทที่แสดงเป็นจำนวนเต็ม  ในการแสดง Access เลยปัดเศษขึ้นเป็น 83 แทนครับ
โพสต์นี้ได้รับคำขอบคุณจาก: Kanxay Vnv

198
น่าจะเพราะตกเครื่องหมาย quote ไป ลองแก้เป็น =DLookup("D1", "DATA", "[D2] = '"& Mid([textbox1],4,4) & "'")
โพสต์นี้ได้รับคำขอบคุณจาก: yot

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