แสดงกระทู้

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 ... 33
1
แนวคิดคือ ผมว่ามองเงื่อนไขของช่วงเวลาที่จะไม่เลือก แล้วใส่ด้วย NOT ครอบเงื่อนไข จะทำให้แก้ปัญหาตรงนี้ได้ง่ายกว่า

ช่วงเวลาที่จะไม่เลือก คือ (ปี = ปีเริ่มต้นที่เลือก และ เดือน < เดือนเริ่มต้นที่เลือก) หรือ (ปี = ปีสุดท้ายที่เลือก และ เดือน > เดือนสุดท้ายที่เลือก) หรือ (ปี < ปีเริ่มต้นที่เลือก) หรือ (ปี > ปีสุดท้ายที่เลือก) เพื่อให้ง่าย ขอเขียนเป็น (P) OR (Q) OR (R) OR (S) แล้วกัน

ดังนั้น ช่วงระยะเวลาที่เลือก (strCriteriaM) ก็คือ NOT ((P) OR (Q) OR (R) OR (S)) นั่นเอง

ลองไปเขียนเป็น expression ดูนะครับ

2
ใครอธิบายให้หน่อย ผมอ่านแล้วไม่เข้าใจ ...  2 คนเปิดฟอร์มเดียวกัน พร้อมกัน นาย ก. ป้อนแล้วบันทึกเรคอร์ด แล้วหน้าฟอร์มของนาย ข. ไม่มีเรคอร์ดที่นาย ก.เพิ่งป้อนโผล่ขึ้นมาให้เห็นแบบอัตโนมัติอย่างงั้นเหรอครับ ?

3
ให้ใช้ Image control สำหรับแสดงรูปภาพ โดยกำหนด Control Source ของ Image control ให้เป็น ="ไดร์ฟ:\พาธ\...\...\พาธ\" & [ชื่อเท็กซ์บ็อกซ์ของ Picturetest]

4
ไม่แน่ใจว่าเป็น bug ตัวนี้หรือไม่ เขาบอกว่าให้อัพเดต mysql เป็นเวอร์ชั่น 8.0.20 ครับ
https://bugs.mysql.com/bug.php?id=98942 link

5
ก็น่าจะเป็น

โค๊ด: [Select]
                rs.Edit
                rs!Password = Me.txtNewPassword
                rs.Update
                rs.Close: Set rs = Nothing
                DoCmd.SendObject ,,,"ผู้รับ@xyz.co.th",,,"ข้อความใน Subject","เนื้อความในเมล์"

6
ถ้าต้องการจัดข้อความให้อยู่กึ่งกลางเซลล์ที่รวม ทั้งแนวตั้งและนอนด้วย เท่าที่คิดออกคือไปสั่งออกรายงานใน Excel แต่เขียนโค้ดเยอะทีเดียว ถ้าจะทำใน Access วิธีเท่าที่คิดออก เป็นแค่การหลอกตาเท่านั้น ข้อความในบรรทัดที่ซ้ำจะหายไปตามต้องการ แต่ข้อความจะยังคงอยู่ที่บรรทัดแรกเสมอ ไม่สามารถไปกึ่งกลางเซลล์ที่รวมได้

วิธีการคือ
- การซ่อนข้อความที่ซ้ำ ให้กำหนด Hide Duplicate property ของเท็กซ์บ็อกซ์ที่แสดง "เหตุผลที่ซื้อ" (สมมุติชื่อ txtReason) เป็น Yes แต่ข้อความนี้จะพิมพ์เสมอเมื่อเป็นบรรทัดแรกของหน้า
- การพิมพ์ขอบของเซลล์ที่รวม เราจะสร้างคอนโทรลของเส้น แทนการใช้กรอบของเท็กซ์บ็อกซ์ ดังนั้น Border Style ของ txtReason กำหนดให้เป็น Transparent ไป ให้สร้างเส้นแนวนอน lineUpper อยู่ที่ขอบบนของ txtReason และให้มีความยาวเท่ากันพอดี  เส้น lineLower วางอยู่ขอบล่าง  เส้น lineRight เป็นแนวตั้งวางอยู่ขอบขวา ส่วนขอบซ้ายคงไม่จำเป็นเพราะเท็กซ์บ็อกซ์ทางซ้ายจะพิมพ์เส้นนั้นอยู่แล้ว   เส้นทั้ง 3 ต้องจัดเลเยอร์ให้อยู่เหนือ txtReason ด้วยนะครับ
- lineUpper จะพิมพ์เมื่อ txtReason พิมพ์ (ซึ่งก็คือบรรทัดแรกของกลุ่มข้อความที่ซ้ำ) โดยเช็คได้จาก .IsVisible property
- lineLower จะพิมพ์เมื่อเป็นบรรทัดสุดท้ายในหน้า ซึ่งต้องใช้เทคนิคให้ระบบรันรายงาน 2 หน (ไม่ใช่เราสั่งพิมพ์ 2 หน) หนแรกเช็คได้จากค่า .Pages property ของ Report object จะเป็นศูนย์ เราใช้หนแรกเพื่อบันทึกว่าบรรทัดไหนเป็นบรรทัดสุดท้ายในแต่ละหน้า โดยบันทึกลงในตัวแปรอะเรย์ A  ค่าของ A(เลขที่บรรทัด) จะเป็น TRUE   ส่วนหนที่สองเพื่อตรวจกับ A ว่า ถ้าบรรทัดที่พิมพ์คือบรรทัดสุดท้ายในหน้านั้น ก็ให้พิมพ์ lineLower
- การบังคับให้ระบบรันรายงาน 2 หน ทำด้วยการสร้างเท็กซ์บ็อกซ์ที่มี Control Source เป็น =[Pages]  เอาไว้ใน Page Header section แต่เราไม่ได้ต้องการจะเห็นมัน เราก็กำหนด Visible property ของเท็กซ์บ็อกซ์ให้เป็น No 
- การที่จะรู้ว่าบรรทัดที่พิมพ์เป็นบรรทัดที่เท่าไหร่ ก็ให้สร้างเท็กซ์บ็อกซ์ txtSeq ที่มี Constrol Source เป็น =1, Running Sum property เป็น Over All และ Visible property เป็น No

อธิบายยืดยาว แต่โค้ดมีสั้นๆแค่
โค๊ด: [Select]
Option Compare Database
Option Explicit

Dim A() As Boolean

Private Sub Detail_Print(Cancel As Integer, PrintCount As Integer)
    Me.lineUpper.Visible = Me.txtReason.IsVisible
    If Me.Pages <> 0 Then Me.lineLower.Visible = A(Me.txtSeq)
End Sub

Private Sub PageFooterSection_Format(Cancel As Integer, FormatCount As Integer)
    If Me.Pages = 0 Then
        ReDim Preserve A(Me.txtSeq)
        A(Me.txtSeq) = True
    End If
End Sub

7
ถ้าหมายถึงชื่อฟิลด์คือ Approved, ชื่อ Option Group คือ O, Checkbox Yes ที่ผูกอยู่ภายใน Option Group ตั้งค่าเป็น 1, No ตั้งค่าเป็นค่าอื่นๆที่ไม่ใช่ 1 

แต่ไม่รู้ว่า O คือค่าที่ต้องการอัพเดตลงเรคอร์ด หรือเป็นเงื่อนไขที่เลือกเรคอร์ดที่จะอัพเดต ถ้าเป็นกรณีแรก ก็จะได้โค้ดเป็นลักษณะ
โค๊ด: [Select]
CurrentDB.Execute "update [P] inner join [I] on [P].[ITEM] = [I].[ITEM] set [P].[Approved] = " & iif(Me.O=1, "TRUE", "FALSE") & " where [I].[PK] = xxx", dbFailOnError
ถ้ากรณีที่สอง ก็จะเป็น
โค๊ด: [Select]
CurrentDB.Execute "update [P] inner join [I] on [P].[ITEM] = [I].[ITEM] set [P].[BALQTY] = [I].[FWQTY] - [I].[ISSUEQTY] where [I].[PK] = xxx and Approved = " & iif(Me.O=1, "TRUE", "FALSE") , dbFailOnError

8
ผมไม่รู้ว่า กรอบแรกและกรอบที่สองจะเป็นข้อความเดียวกันหรือเปล่านะครับ เอาว่าถ้ามันแตกต่างกัน ผลลัพธ์ที่ต้องการจะหมายถึงอย่างนี้หรือเปล่าครับ

9
กำหนด Data Entry property ของฟอร์มให้เป็น Yes แล้วที่ปุ่ม Save ให้เพิ่มโค้ด Me.Requery ต่อท้ายโค้ดที่คุณมีอยู่ก่อนแล้วครับ

10
ทำได้ครับ โดยการใช้คำสั่ง UPDATE sql statement โดยสมมุติชื่อต่างๆดังนี้

ตารางรายการสินค้า P
ฟิลด์รายการสินค้า ITEM
ฟิลด์ยอดคงเหลือ BALQTY

ตารางรายการเบิก I
ฟิลด์รายการสินค้า ITEM
ฟิลด์ยอดยกมา FWQTY
ฟิลด์จำนวนเบิก  ISSUEQTY
ฟิลด์ที่เป็นคีย์ที่ระบุได้ว่าเป็นรายการเบิกรายการนี้ PK เช่น เลขที่เบิก xxx

โค้ดพื้นฐานที่ใช้ก็คือ
โค๊ด: [Select]
CurrentDB.Execute "update [P] inner join [I] on [P].[ITEM] = [I].[ITEM] set [P].[BALQTY] = [I].[FWQTY] - [I].[ISSUEQTY] where [I].[PK] = xxx", dbFailOnError

หมายเหตุ :

- ถ้ายอดยกมา นำมาจากยอดคงเหลืออยู่แล้ว ก็สามารถใช้ set [P].[BALQTY] = [P].[BALQTY] - [I].[ISSUEQTY] แทนก็จะเหมาะสมกว่า

- ส่วน [I].[PK] = xxx หรือส่วนอื่นๆอีก อาจแตกต่างจากนี้ ขึ้นกับว่ามีฟิลด์อะไรบ้างที่ใช้ระบุว่าเป็นเอกสารการเบิกนี้ และค่าของมันมีประเภทข้อมูลตามที่ระบุในตารางว่าเป็น Text หรือ Number

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

11
ห้อง MS Access / : ความเข้าใจ .Tag code vb access
« เมื่อ: 17 ก.ย. 63 , 00:06:50 »
.Tag property คือพื้นที่ว่างๆในคอนโทรลต่างๆที่ให้เราใส่ค่าอะไรลงไปก็ได้ เปรียบเหมือนตัวแปรนึง ไม่มีผลต่อการทำงานหรือคุณสมบัติใดๆต่อตัวคอนโทรลนั้นๆ ความหมายของค่าก็แล้วแต่เราจะกำหนดเอาเอง ในงานที่ผมเคยใช้ ก็เช่นตอนก่อนจะบันทึก ผมก็จะวิ่งอ่านแต่ละคอนโทรลดูว่า .Tag ไหนมีข้อความบ้าง ถ้ามี แต่ผู้ใช้ไม่ได้เป้อนค่าลงคอนโทรลนั้น ก็จะเอาข้อความใน .Tag ไปแสดงเป็นข้อความเตือนให้ผู้ใช้รับรู้ว่าข้อมูลที่ขาดหายไปมีอะไรบ้าง ผมก็จะได้ไม่ต้องมาเขียนโค้ดเช็คทีละคอนโทรล ซึ่งแต่ละฟอร์มก็มีคอนโทรลที่แตกต่างกัน ผมก็จะสามารถเขียนโค้ดเป็น Public Function ที่ทำการเช็คเอาไว้แค่ที่เดียว โค้ดเดียว ก็พอ เช่น ในเท็กซ์บ็อกซ์ Customer Name ผมก็ใส่คำว่า "ชื่อลูกค้า", ในเท็กซ์บ็อกซ์ Purchase Order ก็ใส่คำว่า "เลขที่ใบสั่งซื้อ" เป็นต้น

ส่วนในบรรทัดแรกนั้น เป็นการเช็คว่าถ้า .Tag ไม่มีค่า , แต่จริงๆไม่มีความจำเป็นต้อง & กับ "" เพียงเขียนว่า if txtID.Tag = "" then ก็พอแล้ว

12
เพราะไม่ได้บอกอะไรมาเลย ก็เดานะครับว่า 3 ตำแหน่งที่เป็นสีแดง อาจเป็นจุดที่ทำให้ผิดพลาดได้ นอกจากนี้ ก็เช็คด้วยว่าค่าใน tblKeyword ถูกต้องหรือไม่

                If Len(cc) > 0 Then
                    MST.Open "tblKeyword", CON, adOpenStatic, adLockReadOnly
                ' Do Until MST.EOF <---- Comment ก็ทำให้ไม่วนลูปสิครับ !!
                 '  Debug.Print MST!keyword
                        If cc = MST!Keyword Then <---- เช็คดีๆว่า เปรียบค่าของ cc กับ MST!Keyword ใช่สิ่งที่ต้องการหรือไม่
                 '  MsgBox MST!Category & " --- " & MST!Value
                            TRN.Update MST!Category, MST!Value <---- แน่ใจหรือไม่ว่าอัพเดตด้วย MST!Value
                            ' Debug.Print MST!Category
                        End If
                        MST.MoveNext
                ' Loop
                    MST.Close
                End If

13
Make Table Query พอจะมีอ็อปชั่น IN เพื่อสร้างเทเบิลในฐานข้อมูลอื่นได้ครับ
SELECT field1, field2, ... INTO new_table IN "drive:\path\...\file_name.accdb" FROM source_table;

แต่ก็ตามที่คุณ Unknown บอกครับ เราสามารถ JOIN ลิงค์เทเบิลจากฐานข้อมูลอื่น กับ เทเบิลในฐานข้อมูลเราได้ครับ

14
Shell """c:\program files\7-zip\7z.exe"" a """ & PathString & "\" & "Work.zip" & """ """ & PathString  & "\" & "Work.mdb" & """ "
กรณีข้อความใน PathString มีเครื่องหมาย \ ปิดท้ายอยู่แล้ว ก็ให้เปลี่ยน & "\" & ทั้ง 2 ตำแหน่งเป็น & ก็พอครับ

15
ผมจะใช้คำสั่งแบบ command-line ของโปรแกรมที่ทำการ zip ดังนั้นขึ้นกับว่าโปรแกรม zip ที่ใช้นั้น มี command-line หรือไม่ ถ้ามี คำสั่งมีรูปแบบเป็นอย่างไร ส่วนที่ผมใช้คือ 7-zip เวลาสั่ง zip ก็คือ

if dir("drive:\...ชื่อไฟล์.zip") <> "" then kill "drive:\...ชื่อไฟล์.zip" ' ลบ zip เดิมก่อน
shell """c:\program files\7-zip\7z.exe"" a ""drive:\...ชื่อไฟล์.zip"" ""drive:\...ชื่อไฟล์ที่ต้องการ zip"""


16
DCount("*","Query","[sell]='ขนม'") นับจำนวน ขนม ใน Query ไม่ได้ใช้นับจำนวนที่แสดงในหน้ารายงานครับ

ปัญหานี้ดูเหมือนจะพื้นๆ แต่ก็ไม่ง่ายเสียทีเดียว สิ่งที่จะทำก็คือ รางานจะต้องมี Page Header, Group Header โดยจัดกลุ่มตามชื่ออาหาร (สมมุติว่าชื่อฟิลด์ที่เก็บชื่ออาหารคือ Food) [แก้ไขเพิ่มเติม]และต้องกำหนด Repeat Section property ของ Group Header เป็น Yes เพื่อให้ Group Header ถูกพิมพ์เมื่อเริ่มต้นของทุกหน้าด้วย, มีส่วนของ Detail และ Page Footer เพื่อใส่เท็กซ์บ็อกซ์ SummaryText สำหรับพิมพ์ข้อความสรุปจำนวนอาหารในหน้า  และถึงแม้ว่าคุณจะไม่มีอะไรจะพิมพ์ใน Page Header และ Group Header ก็ตาม แต่ก็ขอให้มีความสูงนิดเดียวก็พอ เพราะต้องเรียกใช้ Print event procedure ของ 2 ส่วนนี้เพื่อเขียนโค้ด



ส่วนโค้ดก็มีตามนี้นะครับ (ถ้าชื่อ section ของคุณต่างออกไป ก็แก้ไขโค้ดด้วย)
โค๊ด: [Select]
Option Compare Database
Option Explicit

' สร้างประเภทข้อมูลเพื่อเก็บชื่ออาหารและจำนวน
Private Type SumText
    Title As String
    Count As Integer
End Type

' สร้างตัวแปรอะเรย์สำหรับประเภท SumText
Dim SumArray() As SumText

Private Sub PageHeaderSection_Print(Cancel As Integer, PrintCount As Integer)
    If PrintCount <> 1 Then Exit Sub
   
    ' เมื่อเริ่มพิมพ์ส่วนหัวกระดาษ ให้ล้างพื้นที่อะเรย์ เพื่อเตรียมรองรับผลรวมในหน้านี้
    ReDim SumArray(0)
End Sub

Private Sub GroupHeader0_Print(Cancel As Integer, PrintCount As Integer)
    If PrintCount <> 1 Then Exit Sub
   
    ' เมื่อเริ่มพิมพ์หัวของกลุ่ม ให้เพิ่มพื้นที่สำหรับอะเรย์อีก 1 element
    ReDim Preserve SumArray(UBound(SumArray) + 1)
End Sub

Private Sub Detail_Print(Cancel As Integer, PrintCount As Integer)
    If PrintCount <> 1 Then Exit Sub
   
    ' ในแต่ละบรรทัดที่พิมพ์ ให้เก็บชื่ออาหารและบวกจำนวนเพิ่มทีละ 1
    With SumArray(UBound(SumArray))
        .Title = Me.Food
        .Count = .Count + 1
    End With
End Sub

Private Sub PageFooterSection_Print(Cancel As Integer, PrintCount As Integer)
    Dim I As Integer
   
    If PrintCount <> 1 Then Exit Sub
   
    ' ล้างข้อความสรุปที่มีในหน้าเก่า
    Me.SumaryText = ""
   
    ' วนตั้งแต่อะเรย์ element แรก ไปจนหมดทุก element
    For I = 1 To UBound(SumArray)
        With SumArray(I)
            ' ใส่ชื่ออาหารและจำนวนนับลงข้อความสรุป
            Me.SumaryText = Me.SumaryText & ", " & .Title & " = " & .Count
        End With
    Next
   
    ' ลบ ", " ตัวแรกในข้อความสรุปทิ้งไป
    Me.SumaryText = Replace(Me.SumaryText, ", ", "", , 1)
End Sub

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