แสดงกระทู้

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 ... 24 25 26 [27] 28 29
469
เข้าใจว่าคงไม่อยากแก้ไขหน้ารายงาน สิ่งที่พอนึกได้คือต้องไปดูก่อนว่าเครื่องพิมพ์มีคุณสมบัติให้ย่อ/ขยายสิ่งที่จะพิมพ์ได้หรือไม่ ซึ่งอาจทำผ่านหน้าจอ LED บนตัวเครื่องพิมพ์เองเลยถ้ามี หรือจะผ่านไดรเวอร์ใน Control Panel ก็แล้วแต่  ถ้าทำได้ก็ค่อยมาทดสอบโดยตั้งขนาดกระดาษของรายงานใน Access ให้ใหญ่เกินข้อมูลที่จะพิมพ์ไปเลย จุดประสงค์คือจะไม่ให้มีการแสดงผลลัพธ์ที่เราเห็นใน Preview ในแบบที่มีข้อมูลล้นไปหน้าอื่นบางส่วน หรือมีหน้าเปล่าแสดงออกมา แล้วค่อยไปพิมพ์จริงออกเครื่องพิมพ์ที่ตั้งค่าย่อส่วนเพื่อให้พอดีหน้ากระดาษ 1 แผ่นอีกที

470
โค้ดนี้พิมพ์ทุก Property ของทุก Control บนฟอร์มที่ระบุตามชื่อออกเท็กซ์ไฟล์ แต่บาง Property อ่านค่าได้เฉพาะเมื่อเปิดฟอร์มใน Design View มั่ง หรือใน Form View มั่ง ดังนั้นผลลัพธ์จึงอาจแตกต่างเมื่อฟอร์มเปิดใน View ที่ต่างกัน และเพื่อไม่ให้เกิด Runtime Error เมื่ออ่าน Property ตัวไหนไม่ได้ จึงใส่ On Error Resume Next เพื่อข้ามตัวนั้นไป

โค๊ด: [Select]
Public Sub DumpProp()
    Dim obj, prop, str As String
   
    On Error Resume Next
    For Each obj In Forms("ชื่อฟอร์ม")
        For Each prop In obj.Properties
            str = str & vbCrLf & obj.Name & vbTab & prop.Name & vbTab & prop.Value
        Next
    Next
   
    Open "ชื่อพาธและไฟล์.txt" For Output As #1
    Print #1, str
    Close #1
End Sub

471
เราลองคิดกลับไปยังระบบที่ออก PO ด้วยมือลงกระดาษ ดูว่าระบบงานเดิมทำยังไง เราอาจต้องออกแบบฐานข้อมูลและการทำงานของโปรแกรมให้ล้อไปกับระบบเดิม เช่น ในวิถีทางการลงบัญชี ถ้านำเข้าระบบแล้วและพบว่ามีอะไรผิด ก็ต้องห้ามแก้ ห้ามลบ แต่เปลี่ยนสถานะว่ายกเลิกใบนั้นไป และออกใบใหม่เท่านั้น ลองถามฝ่ายบัญชีดูครับว่ามีกฏระเบียบทางบัญชีว่ายังไง เพราะอาจต้องรองรับให้ บ.ตรวจสอบบัญชี เข้ามาตรวจสอบข้อมูลได้ด้วยครับ

472
จะไม่บันทึกข้อมูลในเมนฟอร์มถ้าไม่มีข้อมูลในซับฟอร์ม มันค้านกับการทำงานของ Access ครับ แนวคิดที่อาจทำได้ (ไม่รู้ว่าจะเกิดปัญหาอะไรหรือเปล่า เพราะไม่เคยทำ) ก็คือได้แค่กระโดดกลับมายัง PO เลขนั้นเท่านั้น โดยทุกครั้งที่สร้างเรคอร์ดใหม่บนเมนฟอร์ม หรือลบเรคอร์ดในซับฟอร์ม ก็จะเกิด AfterUpdate event บนเมนฟอร์มและ AfterDelConfirm event บนซับฟอร์มตามลำดับ ให้เขียนโค้ดเพื่อเก็บเลขที่ PO เอาไว้ในตัวแปรระดับโมดูล พอไปเรคอร์ดอื่น ซึ่งจะเกิด OnCurrent event บนเมนฟอร์ม ก็ให้เช็คว่าถ้า PO มีค่าและไม่มีเรคอร์ดใน POD ที่มีเลข PO เดียวกันกับที่เก็บไว้ ก็ให้กระโดดกลับไป แต่ถ้ามีแล้ว ก็ให้เคลียร์ตัวแปรนั้นทิ้ง โปรแกรมจะได้ไม่ต้องมาทดสอบ POD ตลอดเวลาครับ

473
แก้อีกทีครับ

If MsgBox("คุณต้องการบันทึกยอดขาย ใช่ หรือ ไม่", vbInformation + vbYesNo, "แจ้งเตือน") = vbYes Then
  If CurrentDb.OpenRecordset("SELECT * FROM Report_Sale WHERE R_DATE = #" & Format(DateAdd("yyyy", -543, Me.Date_Re),"mm/dd/yyyy") & "#").EOF Then
   CurrentDb.Execute "INSERT INTO Report_Sale(R_DATE, R_PRICE, R_SALE,R_CARD,R_CREDIT,R_IN_CREDIT,R_GP) " & _
    "VALUES (#" & Format(DateAdd("yyyy", -543, Me.Date_Re),"mm/dd/yyyy") & "#, " & Me.t01 & ", " & Me.t02 & ", " & Me.t03 & ", " & Me.t04 & ", " & Me.t05 & ", " & Me.t06 & ")", dbFailOnError
  Else
   CurrentDb.Execute "UPDATE Report_Sale SET R_Price = " & Me.t01 & ",R_SALE = " & Me.t02 & ", R_CARD = " & Me.t03 & ", R_CREDIT= " & Me.t04 & ", R_IN_CREDIT = " & Me.t05 & ", R_GP = " & Me.t06 & " WHERE R_DATE = #" & Format(DateAdd("yyyy", -543, Me.Date_Re),"mm/dd/yyyy") & "#", dbFailOnError
  End If
End If

ปล. เชื่อผมเถอะ เปลี่ยนระบบจาก พ.ศ. เป็น ค.ศ.

474
คุณไป Control Panel ของวินโดว์ เลือก Region and Language แล้วแคป แทป Formats หน่อย ผมอยากดูว่าเครื่องกำหนดรูปแบบ Short Date และ Long Date เป็นอะไร

475
ฐานข้อมูลวางไว้ที่เซิร์ฟเวอร์ ตัวโปรแกรมติดตั้งไว้ที่เครื่องแต่ละเครื่อง แล้วสร้างเป็น linked table ไปยังเทเบิลบนฐานข้อมูล ไม่มีการ import อะไรทั้งนั้น มันไม่ช้าหรอกครับ ถ้าช้า ต้องไปหาสาเหตุอื่นๆแล้วครับ

476
ห้อง MS Access / > ซ่อน Page Header
« เมื่อ: 05 มี.ค. 61 , 16:25:15 »
ใส่ใน On Format หรือ On Print event ของ Page Header Section ครับ

477
ห้อง MS Access / > ซ่อน Page Header
« เมื่อ: 05 มี.ค. 61 , 10:45:56 »
Sections("PageHeaderSection") หรือถ้าเป็นชื่ออื่นก็ใส่แทน PageHeaderSection ครับ

478
ฐานข้อมูลแบบ Relational Database ทุกๆยี่ห้อ ทุกเทเบิลต้องมี PK (Primary Key) เพื่อระบุเรคอร์ดไหนคือเรคอร์ดไหน (ถ้าไม่มี ระบบจัดการภายในจะสร้างขึ้นมาเพื่อใช้งานเอง แต่***อาจจะ***ไม่มีบันทึกเป็นฟิลด์ให้ผู้ใช้เห็น)  PK จะมีความหมายหรือไม่มีก็ได้ เช่น อาจใช้เลข 1,2,3,... เป็น PK ก็ได้ แต่ในทางปฏิบัติแล้วเราจะสร้าง PK จากหนึ่งฟิลด์หรือหลายฟิลด์รวมกันโดยที่ค่ารวมของมันจะต้องไม่ซ้ำกันเลย เช่น เลขบัตรประชาชนสำหรับเทเบิลบุคคล หรือใช้เลขที่บ้าน/อาคาร+เลขที่ห้อง+ซอย+ถนน+แขวง/ตำบล+เขต/อำเภอ+จังหวัดสำหรับเทเบิลบ้านอาคารที่อยู่

PK เป็น Index (ดัชนี) ประเภทหนึ่ง และเป็น Unique Index ด้วย (Index ที่ค่าจะไม่มีการซ้ำกันเลยในเทเบิลนั้นๆ) ระบบจัดการฐานข้อมูลจะมีการโยงว่าเรคอร์ดที่มีค่าดัชนีมากกว่า น้อยกว่า เท่ากัน นั้นอยู่ที่ไหน ดังนั้นประโยชน์ของ Index (ไม่ว่าจะ Unique หรือไม่) อีกอย่างก็คือทำให้ระบบสามารถค้นหาเรคอร์ดที่ต้องการได้อย่างรวดเร็วครับ ในทางทฤษฏีแล้ว การค้นหา 1 เรคอร์ดจาก 1 ล้านเรคอร์ดด้วย Unique Index ระบบจะพบเรคอร์ดที่ต้องการภายในการวนหาไม่เกิน 20 ครั้งเท่านั้น

479
ทดลองแล้วพบว่าปัญหาเกิดจากระบบปี พ.ศ. ครับ คำสั่งในโค้ดต้องเปลี่ยนเป็นปี ค.ศ.

โค๊ด: [Select]
If MsgBox("คุณต้องการบันทึกยอดขาย ใช่ หรือ ไม่", vbInformation + vbYesNo, "แจ้งเตือน") = vbYes Then
  If CurrentDb.OpenRecordset("SELECT * FROM Report_Sale WHERE R_DATE = #" & DateAdd("yyyy", -543, Me.Date_Re) & "#").EOF Then
   CurrentDb.Execute "INSERT INTO Report_Sale(R_DATE, R_PRICE, R_SALE,R_CARD,R_CREDIT,R_IN_CREDIT,R_GP) " & _
    "VALUES (#" & DateAdd("yyyy", -543, Me.Date_Re) & "#, " & Me.t01 & ", " & Me.t02 & ", " & Me.t03 & ", " & Me.t04 & ", " & Me.t05 & ", " & Me.t06 & ")", dbFailOnError
  Else
   CurrentDb.Execute "UPDATE Report_Sale SET R_Price = " & Me.t01 & ",R_SALE = " & Me.t02 & ", R_CARD = " & Me.t03 & ", R_CREDIT= " & Me.t04 & ", R_IN_CREDIT = " & Me.t05 & ", R_GP = " & Me.t06 & " WHERE R_DATE = #" & DateAdd("yyyy", -543, Me.Date_Re) & "#", dbFailOnError
  End If
End If

480
โค๊ด: [Select]
    Dim Prev2MM     As Date
    Dim FirstDate    As Date
    Dim LastDate     As Date
   
    ' 2 เดือนก่อนคือวันอะไร
    Prev2MM = DateAdd("m", -2, Date)
   
    ' หาวันที่ 1 ของ 2 เดือนก่อน
    FirstDate = DateSerial(Year(Prev2MM), Month(Prev2MM), 1)
   
    ' หาวันสุดท้ายของเดือนนี้
    ' เท่ากับ วันที่ 1 ของ 2 เดือนก่อน + 3 เดือน - 1 วัน
    LastDate = DateAdd("d", -1, DateAdd("m", 3, FirstDate))
   
    Me.RecordSource = "select * from ชื่อเทเบิล where ชื่อฟิลด์วันที่ between #" & Format(FirstDate, "dd/mmm/yyyy") & "# and #" & Format(LastDate, "dd/mmm/yyyy") & "#"

481
ลองเปลี่ยนจาก
= '" & Me.Date_Re & "'"
เป็น
= #" & Me.Date_Re & "#"

482
ลืมไป อีกวิธีที่ดูง่ายดีก็คือ ลบของเก่าก่อนแล้วค่อยเพิ่มรายการใหม่เข้าไป คำสั่งลบ คือ

โค๊ด: [Select]
DELETE * FROM ชื่อเทเบิล WHERE เงื่อนไข
โค๊ด: [Select]
If MsgBox( ...... ) = vbYes Then
   CurrentDB.Execute "DELETE * from Report_Sale WHERE R_DATE = '" & Me.Date_Re & "'", dbFailOnError
   CurrentDB.Execute "INSERT ... ", dbFailOnError
End If

483
"... แต่มันบันทึกเป็นไฟล์ใหม่ ผมอยากให้มันมันทึกซ้ำวันที่อันเดิมครับ ..." เข้าใจว่าบันทึกเป็นเรคคอร์ดใหม่ใช่ไหม คงไม่ใช่ไฟล์ใหม่อย่างที่คุณเขียน แล้วต้องการบันทึกทับของเดิมใช่ไหมครับ

คำสั่ง INSERT INTO เป็นคำสั่งเขียนเรคอร์ดใหม่ครับ  ถ้าจะเขียนทับหรือแก้ไขเรคอร์ดที่มีอยู่แล้ว ต้องใช้คำสั่ง UPDATE ซึ่งมี syntax คือ
โค๊ด: [Select]
UPDATE ชื่อเทเบิล SET ชือฟิลด์1 = ค่าใหม่, ชือฟิลด์2 = ค่าใหม่, ... WHERE เงื่อนไขแต่การเขียนทับ/แก้ไขเรคอร์ดโดยยังไม่มีเรคอร์ดนั้นมาก่อนตามเงื่อนไขที่ใส่หลัง WHERE  ผลก็คือจะไม่มีเรคอร์ดอะไรถูกแก้ไขเช่นกัน (ส่วนคำสั่ง INSERT จะไม่มี WHERE clause ครับ)

ดังนั้นที่ควรเป็นก็คือ หาโดยคำสั่ง SELECT ก่อนว่ามีเรคอร์ดนั้นหรือยัง ถ้ายัง ก็ให้ INSERT ไม่เช่นนั้นก็ให้ UPDATE 

โค๊ด: [Select]
Private Sub Cmd_Report_Up_Click()

If MsgBox( ...... ) = vbYes Then
   If CurrentDB.OpenRecordset("SELECT * FROM Report_Sale WHERE R_DATE = '" & Me.Date_Re & "'").EOF Then
      CurrentDB.Execute "INSERT INTO Report_Sale(R_DATE, R_PRICE, R_SALE,R_CARD,R_CREDIT,R_IN_CREDIT,R_GP) " & _
      "VALUES ('" & Me.Date_Re & "', " & Me.t01 & ", " & Me.t02 & ", " & Me.t03 & ", " & Me.t04 & ", " & Me.t05 & ", " & Me.t06 & ")", dbFailOnError
   Else
      CurrentDB.Execute "UPDATE Report_Sale SET R_Price = " & Me.t01 & ",   .....   = " & Me.t06 & " WHERE R_DATE = '" & Me.Date_Re & "'", dbFailOnError
   End If
End If
End Sub

หมายเหตุ
1. ตรงที่เขียน .... คุณไปเติมเองนะครับ
2. ยังคงใช้เครื่องหมาย ' เป็นตัวครอบชนิดข้อมูลวันที่ เพราะถ้าใช้ # ในกรณีวันที่เป็นปี พ.ศ. จะวุ่นวายมาก คำสั่ง SQL จะใช้ปี ค.ศ. เท่านั้น ถ้าจะใช้ # จริง ก็ต้องแปลงข้อมูลจากหน้าฟอร์มที่เป็นปี พ.ศ. ให้เป็นปี ค.ศ. อีก แต่การใช้ ' มันจะแปลงเอง แต่กฏเกณฑ์การแปลงเป็นยังไงนี่ผมไม่รู้ อาจเกิดปัญหาตรงไหนผมบอกไม่ได้   ยังไงก็ตาม ผมไม่แนะนำให้ตั้งปฏิทินของวินโดว์ในระบบปี พ.ศ. หรือป้อนข้อมูลเป็นปี พ.ศ. เพราะจะทำให้เกิดข้อผิดพลาดแอบแฝงเอาไว้ได้ โปรแกรมอาจตีความต่างจากที่เราเข้าใจได้ ควรตังเป็นปี ค.ศ.และรูปแบบเป็น ว/ด/ป เท่านั้น และจะใช้ # ได้อย่างไม่ต้องกังวล(เท่าไหร่)
3. แต่ถ้าปัจจุบันระบบวินโดว์เป็นปี ค.ศ. อยู่แล้ว แปลว่าปีของ 23/2/2561 คือปี ค.ศ. 2561 นะครับ ไม่ใช่พ.ศ. 2561

484
1 ที่เห็นแน่ๆหนึ่งจุดคือ CurrentDb.Execute "INSERT INTO Report_Sale(R_DATE, R_PRICE, R_SALE, R_CARD,R_CREDIT,R_IN_CREDIT,R_GP)" & _ ให้เพิ่มอย่างน้อย 1 ช่องว่างที่ด้านหลังวงเล็บครับ

2. ที่ท้ายคำสั่ง CurrentDB.Execute ... Me.t06 & "')" ควรใส่ ,dbFailOnError ต่อท้ายด้วย

3. ที่อาจเกิดปัญหาต่อไปได้ ซึ่งขึ้นกับประเภท (Data Type) ของแต่ละฟิลด์ (R_DATE, R_PRICE, R_SALE, R_CARD,R_CREDIT,R_IN_CREDIT,R_GP) ว่าเป็นประเภทอะไร เพราะคำสั่งคุณมีเครื่องหมาย '  ครอบข้อมูลที่จะเพิ่มทุกฟิลด์ ซึ่งหมายถึงทุกฟิลด์มีประเภทเป็น Text ทั้งหมดเลย แต่ดูแล้วไม่น่าจะเป็นอย่างนั้น ที่ถูกต้องคือ ถ้าเป็นฟิลด์ Number ก็ไม่ต้องมีเครื่องหมาย ' คั่น  ในขณะที่ประเภทของฟิลด์ Date ต้องใช้เครื่องหมาย # คั่น (ประเภทของฟิลด์ต้องดูที่ตัวเทเบิล ไม่ใช่ดูที่เราป้อนอะไรเข้าไปบนหน้าฟอร์ม)

4. ให้เอาบรรทัด On Error Resume Next ออก เพราะคำสั่งนี้จะทำให้ Access ไม่สนใจ error ที่เกิดขึ้น ถ้าเกิด error มันก็จะทำงานคำสั่งถัดไปเลย เราจึงไม่รู้ว่าจริงๆแล้วมี error อะไรเกิดขึ้นบ้าง

485
ตอบอย่างทั่วๆไปคือไม่ได้ แต่มี บ.ฝรั่งที่ต่างประเทศรับทำ แต่จะได้มากน้อยแค่ไหนผมจำไม่ได้แล้ว

486
ถ้า Access 2019 จะมีเพิ่มคุณสมบัติอะไรที่ช่วยให้ชีวิตผู้พัฒนาและผู้ใช้มีความสุขมากขึ้น ก็น่าเปลี่ยนเป็น Windows 10 ครับ (แต่ไม่คาดหวังจะดีกว่า 55)

หน้า: 1 ... 24 25 26 [27] 28 29