แสดงกระทู้

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 ... 15 16 17 [18] 19
307
ห้อง MS Access / > > Update field in table
« เมื่อ: 30 เม.ย. 61 , 19:36:44 »
DoCmd.SetWarnings (0)
...คำสั่งที่ใช้
DoCmd.SetWarnings (1)

TRUE มีค่าเป็น -1 นะครับ ไม่ใช่ 1 แต่ปกติจะเขียนเป็น DoCmd.SetWarnings True หรือ False จะชัดเจนกว่าครับ
โพสต์นี้ได้รับคำขอบคุณจาก: ekppom

308
- ค่า NULL ต้องใช้คำว่า NULL  ไม่ใช่ปล่อยว่างๆ หรือเป็น "" หรือ " "
- ผมเขียน ... หมายถึงข้อความเดิมก่อนหน้าหรือตามหลัง ไม่ใช่ให้ใส่ ...
- ค่าวันที่ที่ใส่ใน SQL ต้องเป็นรูปแบบ #เดือน/วัน/ปีคศ.#
โพสต์นี้ได้รับคำขอบคุณจาก: pirin, sjs, Kxess

309
ห้อง MS Access / > Update field in table
« เมื่อ: 25 เม.ย. 61 , 20:20:26 »
จากที่บอกมา คุณต้องไม่อัพเดตด้วยตัว Actualday ตรงๆ  เพราะการอ้างถึง Actualday ซึ่งเป็นเท็กซ์บ็อกซ์(หรือจะเป็นคอนโทรลอื่นๆก็ตาม)ในส่วนของ Detail section (ส่วนที่แสดงออกมาในแต่ละบรรทัด) บนฟอร์มที่เป็นแบบ Continuous Form หรือ Datasheet Form จะได้ค่าจากบรรทัด(เรคอร์ด)ปัจจุบันเท่านั้น ซึ่งก็คือบรรทัดที่มีเครื่องหมายลูกศรชี้อยู่ที่ด้านหน้าของบรรทัดนั้น ไม่ใช่ค่าที่เปลี่ยนไปตามแต่ละบรรทัดให้อัตโนมัติอย่างที่คิด ดังนั้นจากการอัพเดตก่อนหน้านี้ จึงได้อัพเดตออกมาเป็นค่าเดียวกันหมด คือ 852

สิ่งที่ต้องทำคือ ต้องอัพเดต TOTAL_ActualDay ด้วยสูตรที่ใช้สร้าง Actualday อีกที ถ้าเข้าใจไม่ผิด ก็จะเป็น SumOfSumOfTotal(m2) + Forms![ชื่อฟอร์ม]!ShippingArea และ ShippingArea จะเป็นค่าเดียวกันทุกบรรทัด

ดังนั้น UPDATE Query ที่ควรจะเป็นก็คือ

DoCmd.RunSQL "UPDATE Monthly_FG_Imple_Sum AS M SET M.TOTAL_ActualDay = M.[SumOfSumOfTotal(m2)] + Forms![ชื่อฟอร์ม]!ShippingArea", dbFailOnError
โพสต์นี้ได้รับคำขอบคุณจาก: Earth

310
บอกว่ามีการเชื่อมตาราง 4.. ไปยังตาราง 1.. โดยเรคอร์ดในตาราง 1.. ที่สามารถใช้ได้จะต้องมีค่าในฟิลด์ fgstartcode และ locationstart เดียวกันกับเรคอร์ดในตาราง 4..  ถ้าหากไม่มีที่เหมือนกัน ก็ให้เอามาเฉพาะเรคอร์ดในตาราง 4.. ส่วนฟิลด์ในตาราง 1.. ก็จะให้ค่า NULL แทนทุกฟิลด์

เวลาพิจารณาให้พิจารณาจากตาราง 4.. เป็นตารางเริ่มต้น เพราะเป็นตารางของต้นทางของลูกศร และพิจารณาไปทีละเรคอร์ดครับ
โพสต์นี้ได้รับคำขอบคุณจาก: ekarat

311
ฟิลด์ที่มี Data Type เป็น Number หรือ Currency  เมื่อจะนำข้อมูลเข้าก็ต้องเป็นค่าตัวเลขไม่ก็เป็นคำว่า NULL จะเป็น SPACE หรือ Zero-Length String ไม่ได้ อย่างเช่นที่คุณเขียนว่า Nz(Me![Bill_VAT_Total], "") ถ้า [Bill_VAT_Total] ไม่มีค่า ก็จะกลายเป็น "" ไป คำสั่ง SQL ในส่วนนั้นก็จะออกมาเป็น ... , , ...  ซึ่งการเว้นว่างไม่มีค่าอะไรเลยระหว่างเครื่องหมาย , นั้น ไม่ถูก Syntax ครับ
โพสต์นี้ได้รับคำขอบคุณจาก: Kxess

312
ห้อง MS Access / > สอบถามการQuery คำนวนค่า
« เมื่อ: 18 เม.ย. 61 , 15:47:09 »
คิวรี่ที่1 ไม่ต้องมี Format( )  ให้มาใส่ในคิวรี่ที่ 2 ที่ผมบอกไปครั้งล่าสุด
โพสต์นี้ได้รับคำขอบคุณจาก: Earth

313
ห้อง MS Access / > สอบถามการQuery คำนวนค่า
« เมื่อ: 18 เม.ย. 61 , 14:34:19 »
ฟิลด์ Date ใน StockMonthly_query อย่าไปกำหนดรูปแบบนะครับ มันต้องการ Data Type เป็น DATE ถ้าไปกำหนดรูปแบบแล้ว มันมีความเป็นไปได้ที่จะมี Data Type เป็น TEXT จะทำให้การเรียงข้อมูลทำตามแบบ TEXT แทน

ส่วนถ้าต้องการแสดงเป็น วัน-เดือน ค่อยมาสร้างฟิลด์ ที่ไปกำหนดรูปแบบใน SQL เพิ่มเติม เป็น Select ...+...-...,  Format$(T1.DATE, " dd-mmm") As FormatD., * From ...
โพสต์นี้ได้รับคำขอบคุณจาก: ekarat

314
การนำข้อมูลที่มี Data Type เป็น Date จาก Recordset ไปใส่ลงในเอ็กซ์เซลชีทในเซลที่ถูกกำหนดรูปแบบการแสดงเป็น Custom (รูปแบบที่ผู้ใช้กำหนดเอง เช่นอาจต้องการให้แสดงวันที่ 1 มกราคาม 2561 เป็น "จันทร์ 1 ม.ค. 61") ด้วยคำสั่ง CopyFromRecordset method สำหรับ Range object (เป็น Excel object) จะทำให้เซลนั้นจะถูกเซ็ท format กลับมาเป็นชื่อ Date เสมอ ต้องกำหนดรูปแบบของเซลอีกครั้งด้วย NumberFormat property  แต่ถ้าใส่ค่าลงไปตรงๆด้วย Value property จะไม่เกิดเหตุการณ์แบบนี้

โค้ดตัวอย่างที่ทำให้เกิดเหตุการณ์
โค๊ด: [Select]
    Dim xlApp   As Object
   
    Dim DB      As DAO.Database
    Dim RS      As DAO.Recordset
   
    Set xlApp = CreateObject("Excel.Application")
    xlApp.Visible = True
    xlApp.Workbooks.Open "C:\Temp\Example.xlsx"
   
    Set DB = CurrentDb
    Set RS = DB.OpenRecordset("select PMU2_StartDT from PMU2")
    xlApp.ActiveSheet.Range("C3").CopyFromRecordset RS
    RS.Close

ภาพเซลที่มีรูปแบบตามที่ผู้ใช้กำหนดเอง
โพสต์นี้ได้รับคำขอบคุณจาก: PookPuy, OddyWriter

315
ห้อง MS Access / > > สอบถามการQuery คำนวนค่า
« เมื่อ: 10 เม.ย. 61 , 17:37:30 »
ข้อมูลแยกตามItemID ค่ะ และลำดับวันที่ก่อน ไปหลัง
ตามรูปใหม่ด้านล่างค่ะ



งั้นตามคิวรี่ที่ผมให้ไปก็ควรจะให้ผลลัพธ์ที่ถูกต้องแล้วครับ
โพสต์นี้ได้รับคำขอบคุณจาก: Earth

316
ห้อง MS Access / > สอบถามการQuery คำนวนค่า
« เมื่อ: 10 เม.ย. 61 , 16:46:57 »
สมมุติเทเบิล T มีฟิลด์รายการสินค้า ItemCD, วันที่ D, ยอดยกมา BFQty, จำนวนรับเข้าในวันนั้น InQty, จำนวนจ่ายออกในวันนั้น OutQty  และมี Primary Key เป็น ItemCD, D

คิวรี่คือ
SELECT T1.BFQty+(select nz(sum(T2.InQty),0) from T as T2 where T2.ItemCD = T1.ItemCD and T2.D <= T1.D)-(select nz(sum(T2.OutQty),0) from T as T2 where T2.ItemCD = T1.ItemCD and T2.D < T1.D) AS TotalQty, *
FROM T AS T1
ORDER BY T1.ItemCD, T1.D;

ความหมายคือ

T1.BFQty
ยอดยกมา

+ (select nz(sum(T2.InQty),0) from T as T2 where T2.ItemCD = T1.ItemCD and T2.D <= T1.D)
+ ผมรวมของจำนวนรับเข้าสำหรับสินค้าเดียวกันตั้งแต่วันแรกจนถึงวันนั้น (วันของเรคอร์ดนั้น)

(select nz(sum(T2.OutQty),0) from T as T2 where T2.ItemCD = T1.ItemCD and T2.D < T1.D)
-  ผมรวมของจำนวนจ่ายออกสำหรับสินค้าเดียวกันตั้งแต่วันแรกจนถึงก่อนวันนั้น (วันของเรคอร์ดนั้น)

ที่ต้องใส่ฟังก์ชั่น nz( ) เพราะถ้าผลรวมนั้นไม่มีมาก่อน เช่นจำนวนจ่ายออกของวันที่น้อยกว่าวันแรก ซึ่งไม่มีค่า จะไม่ใช่ศูนย์ แต่เป็น NULL ซึ่งพอเอามาคำนวนกับค่าอื่นแล้ว จะให้ผลลัพธ์ซึ่งก็คือช่อง TotalQty ของเรคอร์ดนั้นเป็น NULL ไปด้วย ดังนั้นถ้าต้องการให้เป็นศูนย์ เราจึงต้องใส่ฟังก์ชั่น nz(... , 0) เพื่อแปลงค่า NULL เป็นศูนย์แทน
โพสต์นี้ได้รับคำขอบคุณจาก: Earth

317
ถ้าไม่มีเชื่อมเทเบิลอื่นต่อไปอีกแล้ว ก็ไม่ต้องมีคำว่า UNION ALL ปิดท้ายครับ
โพสต์นี้ได้รับคำขอบคุณจาก: prajak

318
เวลาเราดีบักโปรแกรม โค้ดจะหยุดรันเมื่อถึงบรรทัดที่ตั้ง break point ไว้ ปกติเมื่อกดคีย์ F8 โค้ดก็จะทำงานต่อไปหนึ่งบรรทัดและหยุดรอเราว่าจะให้ทำอะไรต่อไป แต่บางกรณีที่โค้ดนั้นเขียนเพื่อโปรแกรมการทำงานของ Excel เช่น

1410              xlSheet.Cells(wR, wxlOut_ColIDLine) = wRS!PMU2_ID
1420              xlSheet.Cells(wR, wxlOut_ColStartDT) = wRS!PMU2_StartDT
1430              xlSheet.Cells(wR, wxlOut_ColMatCD) = wRS!PMU2_MATCD

สมมุติว่าตั้ง break point ไว้ที่บรรทัด 1410  พอโค้ดหยุดแล้ว และเรากดคีย์ F8  แทนที่โค้ดจะหยุดที่บรรทัด 1420  ปรากฏว่าโค้ดจะไม่หยุด และทำงานต่อไปตามปกติ ถ้าอยากให้หยุดที่บรรทัด 1420 ก็ต้องตั้ง break point ไว้ที่นั่นอีกบรรทัด แต่จะไม่เกิดปัญหานี้ในโค้ดที่ควบคุมการทำงานของ Access เอง สาเหตุเป็นปัญหาทางเทคนิคของตัว VBA เอง วิธีแก้ก็คือให้แก้ไข Registry ในระบบวินโดว์ตามลิงค์นี้ครับ http://www.contextures.com/excelvbatips.html#f8 (ดูในส่วน F8 Key Stops Working)

หมายเหตุ : ปัญหานี้สามารถเกิดได้เมื่อเขียน VBA ภายในตัวโปรแกรม Excel เองโดยตรงด้วย
โพสต์นี้ได้รับคำขอบคุณจาก: PookPuy, OddyWriter

319
ให้ตาราง A ชื่อ TA มีฟิลด์ชื่อ DateA
ให้ตาราง B ชื่อ TB มีฟิลด์ชื่อ DateB และ Output
ให้ตาราง C ชื่อ TC มีฟิลด์ชื่อ DateC และ Output
...

ให้สร้างคิวรี่ชื่อ JoinOutput ซึ่งมี SQL เป็น
SELECT TA.DateA, TB.Output, "OutputB" AS HeadName FROM TA LEFT JOIN TB ON TA.DateA = TB.dateB
UNION ALL
SELECT TA.DateA, TC.Output, "OutputC" AS HeadName FROM TA LEFT JOIN TC ON TA.DateA = TC.dateC
UNION ALL
...

ให้สร้างคิวรี่ชื่อ FinalOutput ซึ่งมี SQL เป็น
TRANSFORM Sum(JoinOutput.Output) AS SumOfOutput
SELECT JoinOutput.DateA
FROM JoinOutput
GROUP BY JoinOutput.DateA
PIVOT JoinOutput.HeadName;

รัน FinalOutput ก็จะได้ผลลัพธ์ที่ต้องการครับ
โพสต์นี้ได้รับคำขอบคุณจาก: PookPuy, prajak, royaltool

320
เข้าใจว่าคงไม่อยากแก้ไขหน้ารายงาน สิ่งที่พอนึกได้คือต้องไปดูก่อนว่าเครื่องพิมพ์มีคุณสมบัติให้ย่อ/ขยายสิ่งที่จะพิมพ์ได้หรือไม่ ซึ่งอาจทำผ่านหน้าจอ LED บนตัวเครื่องพิมพ์เองเลยถ้ามี หรือจะผ่านไดรเวอร์ใน Control Panel ก็แล้วแต่  ถ้าทำได้ก็ค่อยมาทดสอบโดยตั้งขนาดกระดาษของรายงานใน Access ให้ใหญ่เกินข้อมูลที่จะพิมพ์ไปเลย จุดประสงค์คือจะไม่ให้มีการแสดงผลลัพธ์ที่เราเห็นใน Preview ในแบบที่มีข้อมูลล้นไปหน้าอื่นบางส่วน หรือมีหน้าเปล่าแสดงออกมา แล้วค่อยไปพิมพ์จริงออกเครื่องพิมพ์ที่ตั้งค่าย่อส่วนเพื่อให้พอดีหน้ากระดาษ 1 แผ่นอีกที
โพสต์นี้ได้รับคำขอบคุณจาก: Eik Q Sang

321
โค้ดนี้พิมพ์ทุก 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
โพสต์นี้ได้รับคำขอบคุณจาก: bgfc, อุดมโชค สมหวัง

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

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

324
ห้อง MS Access / > ซ่อน Page Header
« เมื่อ: 05 มี.ค. 61 , 16:25:15 »
ใส่ใน On Format หรือ On Print event ของ Page Header Section ครับ
โพสต์นี้ได้รับคำขอบคุณจาก: Un

หน้า: 1 ... 15 16 17 [18] 19