แสดงกระทู้

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 - diehard4

หน้า: [1]
1
เครื่องหมาย  %  น่าจะเปลี่ยนเป็น  *  แทนครับ
โพสต์นี้ได้รับคำขอบคุณจาก: diehard4

2
ผมไม่เคยใช้ 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
โพสต์นี้ได้รับคำขอบคุณจาก: diehard4

3
ขออนุญาตใช้กระทู้นี้ต่อคำถามเพิ่มเติมนะคะ
 หนูมีโปรเจ็คชื่อ Sample หนูลองนำคำสั่งในนี้ไปประยุกต์ใช้เป็นดังนี้
โค๊ด: [Select]
oFSO.CopyFile CurrentProject.Path & "\" & CurrentProject.Name, "D:\" & "Backup " & CurrentProject.Name
ซึ่งมันก็ใช้ได้ดีเลยทีเดียว โดยจะได้ไฟล์สำรองเป็น BackupSample ตามที่ต้องการ
ประเด็นปัญหาก็คือ หากเราไปเปิดตัวไฟล์สำรอง BackupSample แล้วสั่งสำรองข้อมูล
มันก็จะได้ไฟล์สำรองตัวใหม่เป็น BackupBackupSample

หนูจึงอยากได้ว่า หากมีการเปิดไฟล์โปรเจ็คที่ มีชื่อขึ้นต้นว่า Backup
ก็ให้มีข้อความบอกผู้ใช้ว่า"ไฟล์นี้เป็นไฟล์สำรองไม่ควรเปิดใช้งานจนกว่าจะเปลี่ยนชื่อไฟล์ใหม่" ประมาณนี้ค่ะ
ไม่ทราบว่าต้องทำอย่างไรคะ

สร้าง Function มาเช็คดูก็ได้คับ ว่าไฟล์เปิดใช้งานจริงหรือไม่

โค๊ด: [Select]
Function checkFileOpen(FilePath As String)
    Dim iFile As Long
    Dim OnErr As Long
    On Error Resume Next
    iFile = FreeFile()
    Open FilePath For Input Lock Read As #iFile

    Close iFile
    OnErr = Err
    On Error GoTo 0
     
    Select Case OnErr
    Case 0:    checkFileOpen = False
    Case 70:   checkFileOpen = True
    End Select
     
End Function

Private Sub Command0_Click()
Dim oFSO As Object
Set oFSO = CreateObject("Scripting.FileSystemObject")

If checkFileOpen("D:\" & "Backup " & CurrentProject.Name) = False Then
   oFSO.CopyFile CurrentProject.Path & "\" & CurrentProject.Name, "D:\" & "Backup " & CurrentProject.Name
   Set oFSO = Nothing
   
Else
    MsgBox "ไฟล์นี้เป็นไฟล์สำรองไม่ควรเปิดใช้งานจนกว่าจะเปลี่ยนชื่อไฟล์ใหม่", vbInformation, "แจ้งเตือน"
End If
End Sub
โพสต์นี้ได้รับคำขอบคุณจาก: diehard4

4
เนื่องจาก 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

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

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

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

6
สร้าง แถบ Ribbon มาใช้เองก็ได้คับ แล้วเลือก สัญลักษณ์เครื่องปริ้นมาแสดงไว้พอจะปริ้น ก็ Ribbon เอาเลย
โพสต์นี้ได้รับคำขอบคุณจาก: diehard4

7
1.เป็นเพราะการป้องกันการคลิกขวาไว้ หรือ
2.เป็นเพราะตั้งค่าตัวเลือกแถบเครื่องมือ ไม่ติ๊กถูกหน้าข้ออนุญาตให้ใช้เมนูทางลัดเบื้องต้น หรือทั้ง2ข้อ
วิธีแก้หากทำข้อที่1และ2ไม่ได้ ให้กดปุ่มCtrl+P พร้อมกันครับ
โพสต์นี้ได้รับคำขอบคุณจาก: diehard4

8
ห้อง MS Access / : Running Number ใน Query Group By Type
« เมื่อ: 28 เม.ย. 62 , 17:18:02 »
RunningNo.    Price      Type
1                   100        A
2                   120        A
3                   130        A
1                   80          B
2                   90          B
1                   78          C
2                   80          C
3                   90          C
4                  100         C

ไม่ทราบว่า ใน Query แบบนี้ ต้องทำเช่นไรครับผม  :question:

ตามนี้เลยคับ
ผมสมมุติตารางที่ทำชื่อ Table1 นะครับ มีฟิล์ Type กับ Price ตามตัวอย่าง

SELECT T.*, (select count(*) from Table1 where T.Price>=Price and  T.Type=Type) AS RunningNo
FROM Table1 AS T
ORDER BY T.Type, T.Price;
โพสต์นี้ได้รับคำขอบคุณจาก: diehard4

9
เช่น พนักงาน ID  A001 อยากจะให้ดึงรูปภาพ ของพนักงานคนนั้น มาแสดงในฟอร์ม หรือ รายงาน โดยอยากให้ผูก ID กับชื่อ image file ทำอย่างไรครับ

\images\A001.jpg
\images\A002.jpg
\images\A003.jpg
\images\A004.jpg

ขอบคุณมากครับ


มีให้ลองนำไปใช้ดู 2 แบบนะครับ
ถ้าในฟอร์มหรือรายงาน ท่านเอา Field ID เข้ามาใส่ไว้ด้วย และ ตั้งชื่อ Textbox ว่า ID เราก็สามารถกำหนดค่าให้กับ กรอบ Image ที่ต้องการได้ครับเช่น
แบบที่ 1 เขียนโค้ดบนฟอร์มหรือรายงาน
Private Sub Form_Current()
Call PathOfImage
End Sub

Sub PathOfImage()
Dim StrPath, StrPathDir As String
StrPath = "C:\images\" & Me.ID & ".JPG"  'กำหนด Path ของรูปภาพโดยอ้างอิงไปที่ textbox ID
StrPathDir = Dir(StrPath) 'ตรวจสอบดูก่อนว่ามีไฟล์รูปชื่อนี้อยู่จริงหรือไม่
If StrPathDir <> "" Then 'ถ้าตรวจสอบแล้วมีอยู่จริง
Me.Image.Picture = StrPath 'ถ้ามีอยู่ก็ให้กำหนด Path ให้กับ Image
Else
Me.Image.Picture = "" 'ถ้าไม่เจอไฟล์รูปที่ตรงกับ ID ของเราก็ให้แสดงกรอบว่างๆไป
End If
End Sub

แบบที่ 2 สร้าง Calculate Field
สร้าง Field Calculate มาแล้วใส่ค่าไปว่า
"C:\images\" & [ID] & ".JPG"
แล้วท่านก็ไปกำหนดแหล่งตัวควบคุมของ Image เอาท่านก็จะได้ ลิ้งอัตโนมัติเลยคับ

ผมมีตัวอย่างให้ท่านคลาย Zip ไปไว้ที่ Drive C แล้วลองเทสดูคับ
โพสต์นี้ได้รับคำขอบคุณจาก: diehard4

10
ถ้าหมายถึงการใส่ Caption ให้พิมพ์เป็นสองตัวครับ && จะได้เป็น & ตัวเดียว
โพสต์นี้ได้รับคำขอบคุณจาก: diehard4

11
สมมุติชื่อฟิลด์คือ N และ P สำหรับชื่อและคะแนน  และชื่อเท็กซ์บ็อกซ์ชื่อ txtS, txtN และ txtP ตามลำดับ ให้สร้างเท็กซ์บ็อกซ์ txt1 เพิ่มเพื่อแสดงลำดับแทน txtS   ส่วน txtS ให้กำหนด Visible property เป็น False แทน   ให้ใส่ Control Source property ของ txt1 เป็น

= iif( [txtN] = Dmin("N","ชื่อเทเบิล","P = [txtP]") , [txtS] , "" )   (ต้องมีเครื่องหมาย = ด้วย)
โพสต์นี้ได้รับคำขอบคุณจาก: diehard4

12
ขอบคุณค้า อันแรกทำได้แล้วค่ะ เหลือแสดงวันที่ค่ะ
ทำคิวรี่แรกก่อนแบบนี้ครับ

โค๊ด: [Select]
SELECT format(StockDate,"DD-MMM"), Takein, TakeOut, Balance
FROM StockBefore
UNION SELECT format(StockDate,"DD-MMM"), Takein, TakeOut,  '' as Balance
FROM StockCard;

อันตอนต่อไป กำหนด วันที่ โดยรันวันที่ลงมา ผมใช้ การสร้างตาราง ขึ่นมามี 365 วัน ตัวอย่างคำสั่ง สร้างตารางที่จะเก็บไว้ชื่อ TempDate365 ตั้งชื่อ Field ว่า Stockdate
บน Module
โค๊ด: [Select]
Option Compare Database
Public Sub MakeDate365(Optional ByVal pYear As Integer, _
        Optional ByVal pTable As String = "TempDate365", _
        Optional ByVal pField As String = "Stockdate")
    Dim db As DAO.Database
    Dim dte As Date
    Dim dteLast As Date
    Dim intYear As Integer
    Dim rs As DAO.Recordset
    Dim strMsg As String

On Error GoTo ErrorHandler

    intYear = IIf(pYear = 0, Year(Date), pYear)
    dte = DateSerial(intYear, 1, 1)
    dteLast = DateSerial(intYear, 12, 31)

    Set db = CurrentDb
    Set rs = db.OpenRecordset(pTable, dbOpenTable, dbAppendOnly)

    Do While dte <= dteLast
        rs.AddNew
        rs.Fields(pField).Value = dte
        rs.Update
        dte = dte + 1
    Loop
    rs.Close

ExitHere:
    On Error GoTo 0
    Set rs = Nothing
    Set db = Nothing
    Exit Sub

ErrorHandler:
    strMsg = "Error " & Err.Number & " (" & Err.Description _
        & ") in MakeDate365"
    MsgBox strMsg
    GoTo ExitHere
End Sub



สร้างคิวรี่ใหม่ ชื่อ  StockQuery2
กำหนดค่าดังนี้
โค๊ด: [Select]
SELECT TempDate365.StockDate, IIf(IsNull([Takein]),0,[Takein]) AS Take_in, IIf(IsNull([Takeout]),0,[Takeout]) AS Take_out, (select  [BeforeQty] from [StockBeforeQuery] ) AS Before_Qty
FROM StockQuery RIGHT JOIN TempDate365 ON StockQuery.StockDate = TempDate365.StockDate
WHERE (((TempDate365.StockDate) Between [forms]![Main]![StockBefore] And [forms]![Main]![EndDate]));

ที่คิวรี่ตัวต่อไป ชื่อ StockQuery3
โค๊ด: [Select]
SELECT T1.[Before_Qty]+(select nz(sum(T2.Take_in),0) from StockQuery2 as T2 where  T2.StockDate <= T1.StockDate)-
(select nz(sum(T2.Take_out),0) from StockQuery2 as T2 where T2.StockDate <= T1.StockDate) AS TotalQty, *
FROM StockQuery2 AS T1
ORDER BY T1.StockDate;

ผลลัพท์ที่ได้


ตัวอย่างด้านล่าง
โพสต์นี้ได้รับคำขอบคุณจาก: diehard4

หน้า: [1]