10 พฤศจิกายน 2554

Someone Like You (Piano Cover)

ฟังเพลง Someone Like You เล่นตอนน้ำท่วมจะเป็นอย่างไร ลองคลิกดู

เมื่อ Adobe ยุติการพัฒนา Flash บนอุปกรณ์ Mobile

วันที่ 9 พ.ย. 54 เป็นวันหนึ่งที่ Adobe Flash ได้ประกาศหยุดการพัฒนา Flash ที่ใช้กับ Mobile Web Browser ซึ่งอนาคตก็แน่นอนแล้วว่า มือถือทั้งหลาย หรือ อุปกรณ์ที่ใช้ OS Android (iPad, iPhone เปิดไม่ได้ตั้งแต่แรก) เมื่อเปิด Web Browser ก็คงไม่มี Flash สวย ๆ มาให้เราเห็นอีกต่อไป ซึ่งก็คงต้องปล่อยให้เป็นหน้าที่ของ HTML5 เป็นตัวชูโรงสำหรับอนาคตข้างหน้า
เหตุที่เป็นเช่นนี้ ก็เนื่องมาจากเอกสาร Flash กินทรัพยากรของเครื่องมากไป แล้ว Flash จะทำอย่างไรดี การพัฒนาที่ทาง Adobe บอกไว้ว่า Flash จะพัฒนาให้ใช้ได้บน Mobile ที่เป็น Mobile Application เท่านั้น เพราะถ้าทำ ให้ใช้ได้กับ Web ด้วยก็คงต้องทุ่มสรรพกำลังจนเกินเหตุ ได้ไม่คุ้มเสีย เลิกดีกว่า
สาวก Flash ที่พัฒนาบน Web ต่อไปก็คงต้องปรับตัว ในอนาคตเมื่อ Mobile Web Browser ไม่ support แล้วคนที่จ้างทำ Flash ลงหน้าเว็บ ฤาจะให้ใช้ Flash ทำเฉพาะ Web browser บน Desktop ก็กระไรอยู่ คงไม่มีใครมาจาก 2 ต่อ ทั้งบน web browser บน Windows และ Mobile ซึ่งใช้เครื่องมือคนละตัว ใครที่เขียน Web ด้วย Flash ก็คงต้องปรับไปใช้ HTML5 ในไม่ช้า แต่ทาง Adobe ก็ไม่ได้ทิ้ง Flash หันไปทางด้าน Mobile Application แทน โดยผ่านทาง Adobe Air ดังนั้น ใครใช้ Flash ใช้ Action Script ก็คงยังไม่หมดหนทางเสียทีเดียว ก็พัฒนาเป็น Mobile Application ถ้าท่านใดมี Adobe Flash 5 หรือ 5.5 ขึ้นไปก็สามารถเขียน Mobile Application ได้เลยไว้ว่าง ๆ เรามาเขียนกัน

โลกยังดำเนินต่อไป มีเกิดมีดับ มีรุ่งมีร่วง ช่วงนี้น้ำท่วม มีท่วมก็มีลด
ถึงแม้ว่า Flash จะไม่สามารถใช้กับ Mobile Web Browser แต่เราใช้กับงานอื่นได้อีกเยอะ
ช่วงหลัง ผู้เขียนมุ่งไปทาง ตาดูหูฟัง นั่งทำตาม เลยจัดทำเป็นวีดีโอช่วยเรียนรู้ ว่าง ๆ ก็เปิดดูได้ มี 2 เรื่อง
(จริง ๆ มีทำไว้มากกว่านี้ลองหาดู)
วีดีโอ แรก มาเขียนเกมเล่น ด้วย Flash กันดีกว่า


วีดีโอ ที่สอง มาทำโปรแกรมเปิดไฟล์วีดีโอ ไว้เผื่อทำวีดีโอช่วยสอนใส่แผ่นซีดี แจกจ่ายได้



บ้านใครน้ำท่วมก็ขอให้น้ำลดไว ๆ

24 สิงหาคม 2554

เรียนภาษาอังกฤษ

เว็บไซต์เรียนภาษาอังกฤษ
มีให้เราเรียนเยอะแยะมากมาย เรียนวันละนิด รับรองเก่งแน่ ๆ

http://www.lextutor.ca/

ด้านล้างก็เป็นแบบทดสอบ ดูซิว่าเราเก่งขนาดไหนแล้ว
http://www.er.uqam.ca/nobel/r21270/levels/

15 มิถุนายน 2554

ของดี มีอยู่ใน Visual Studio Gallery

สามารถเข้าไป ดาวน์โหลดได้ที่ http://visualstudiogallery.msdn.microsoft.com/

ที่ codeplex รวมไว้หลากหลาย เข้าได้ที่ http://1code.codeplex.com/wikipage?title=All-In-One%20Code%20Framework%20Sample%20Catalog

upgrade Visual Studio 2010

เมื่อเราไป ดาวน์โหล Visual Studio 2010 รุ่นทดลอง มาใช้ได้สักพัก แล้วเกิดติดใจ ดังนั้นต้องไปซื้อ License มา เมื่อได้ product key มาแล้ว ต้องการจะ upgrade จากรุ่นทดลองเป็นรุ่นจริง สามารถทำได้ดังนี้
1. ทำการเปิดแฟ้ม setup.sdb ที่เก็บไว้ในโฟล์ดเดอร์ของโปรแกรม (C:\Program Files\Microsoft Visual Studio 10.0\setup.sdb) ด้วยโปรแกรม notepad
2. หาบรรทัด [Product Key] แล้วแก้ product key ที่อยู่ใต้ section นี้ เป็นตัวที่ได้ซื้อมา
3. ทำการบันทึกไฟล์ แต่ถ้าหากบันทึกไม่ได้ ก็บันทึกไว้ที่อื่น แล้วค่อยใช้ windows expoler ลากไปวางแทนไฟล์เดิมที่ในโฟล์ดเดอร์ของโปรแกรม
4. ที่โฟล์ดเดอร์ของโปรแกรม หาไฟล์ setup.exe เรียกไฟล์นี้ขึ้นมา ในนี้จะมีให้ใส่ product key ก็เอาตัวที่ได้ซื้อมาใส่ไปอีกครั้ง เป็นอันเสร็จ

06 พฤษภาคม 2554

app.config เก็บอะไรได้หลายอย่าง

ใน VB.NET App.Config เอาไว้ทำอะไร คงมีคำถามมากมาย ???
เอากันตรงตัวเลย App = Application + Config = Configuration
เว้ากันซื่อ ๆ ก็ เอาไว้กำหนดค่าต่างๆของแอพพลิเคชัน เพื่อเอาไว้ใช้งานในระบบงาน

เช่น การกำหนดค่าต่าง ๆ เช่น กำหนดค่าคงที่, กำหนด Connectionstring เป็นต้น

เราสามารถสร้างไฟล์ app.config ในโปรเจกต์ ได้โดย
1. เลือกเมนู Project
2. เลือก Add New Item...
3. ที่รายการ Common Items เลือก General แล้วเลือกรายการ Application Configuration File
ที่ช่อง Name จะมีชื่อ app.config ให้คลิก OK

เราจะได้ไฟล์ ชื่อ app.config ปรากฎอยู่ในหน้าต่าง Solution Explorer
ให้ทำการเปิดขึ้นมาดู แล้วเพิ่มโค้ด ภายใต้บล๊อกคำสั่ง <appSettings> ... </appSettings> ดังนี้

<?xml version="1.0" encoding="utf-8" ?>

 <configuration>

  <appSettings>

   <add key="name" value="Kasem"/>

   <add key="surname" value="Kamolchaipisit"/>

  </appSettings>


 </configuration>

หากเราต้องการเรียกใช้งานค่าจากไฟล์ app.config
ให้ทำการ Imports System.Configuration ก่อน เช่น


' ประกาศไว้ต้นโปรแกรม
Imports System.Configuration
' คำสั่งในโปรแกรม
' ...

' การเรียกใช้งาน
Dim appSet As New AppSettingsReader()
' หาต้องการดึงค่าใน app.config มาเก็บไว้ในตัวแปร หรือนำไปใช้ตามต้องการ เขียนคำสั่ง ดังนี้
Dim myName , mySurname As String 
MyName = appSet.GetValue("name", GetType(String))  

' name คือชื่อของ key ใน app.config
MySurname = appSet.GetValue("surname", GetType(String))

' surname คือชื่อของ key ใน app.config
Messagebox.Show(MyName & "  " & MySurName)  ' จะปรากฎชื่อ Kasem Kamolchaipisit



หลายคนที่เขียนโปรแกรมจะประกาศ Connection String ไว้ในฟอร์มที่ทำงานโดยตรง ซึ่งมีข้อเสีย ถ้าต้องการเปลี่ยนค่าของ Connection String ใหม่ ก็ต้องแก้ไขฟอร์มทุกฟอร์มใหม่ สำหรับ app.config ก็ให้เราสามารถกำหนดค่าของ Connection String ได้แล้วนำไปใช้ภายใต้ฟอร์มต่าง ๆ ดังนั้นหากต้องการแก้ไขค่า ก็สามารถทำได้ใน app.config ที่เดียวซึ่งก็จะทำให้ทุกฟอร์มสามารถเรียกใช้ได้ทันที่
สำหรับการประกาศ Connection String ภายใต้ไฟล์ app.config เราจะเขียนไว้ภายใต้บล๊อกคำสั่ง <connectionStrings>...</connectionStrings> เช่น

<connectionStrings>

  <add name="myConnect" connectionString=""Data Source=ชื่อเซิร์ฟเวอร์;Initial Catalog=ชื่อฐานข้อมูล;Integrated Security=True" providerName="System.Data.SqlClient" />

</connectionStrings>

จากนั้นที่ฟอร์มแต่ะลฟอร์ม เมื่อต้องการเชื่อมต่อฐานข้อมูลแล้วเรียกใช้งาน Connection String ก็ให้ทำการ Imports คลาส ดังนี้

Imports System.Configuration

จากนั้นเขียนคำสั่งเรียกใช้งาน connection string โดยเขียนไว้หลังจาก Public Class ชื่อ Class เช่น

Imports System.Data
Imports System.Data.SqlClient
Imports System.Data.Configuration

Public Class Form1
Dim cs As String = ConfigurationSettings.AppSettings("myConnect")

Private Sub Form1_Load .....
' เขียนคำสั่งติดต่อตามต้องการ
End Sub
End Class

สวัสดี

10 กุมภาพันธ์ 2554

VB.Net กับ Transaction

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

ตัวอย่าง เช่น การโอนเงินผ่านธนาคาร จาก นาย ก.  ไปให้ นาย ข. ถ้าเรามองการทำงานเวลาเราไปโอนเงินผ่านตู้ ATM เราจะเห็นว่ามีการทำงานแค่ครั้งเดียว คือ นาย ก. ไปโอนเงิน (เป็นการมองในระดับ High Level) แต่ในอีกมุมนึง การทำงานของโปรแกรม ซึ่งเป็นส่วนของการประมวลผลคำสั่งและปรับปรุงข้อมูลลงฐานข้อมูล จะเกิดขั้นตอนการปรับปรุงข้อมูลอย่างน้อย 2 คำสั่ง (มองในระดับ Low Level) คือ คำสั่งแรก จะต้องปรับปรุงข้อมูลของนาย ก. โดยลดยอดลง  คำสั่งที่สอง จะเป็นการปรับปรุงข้อมูลโดยการเพิ่มเงินในบัญชีของนาย ข. ลักษณะนี้ เราจำเป็นต้องมีการทำ Transaction เพื่อป้องกันเหตุสุดวิสัยที่อาจจะทำให้การปรับปรุงข้อมูลข้างต้นไม่ให้เกิดข้อผิดพลาดในการปรับปรุงข้อมูลเกิดขึ้น

คุณสมบัติของทรานแซกชัน ประกอบด้วย
1. Atomicity คือ ความเป็นหนึ่งเดียว : การทำงานของกลุ่มคำสั่งภายใต้ทรานแซกชันจะถูกประมวลผลเสมือนเป็นคำสั่งเดียวกัน
2. Consistency คือ ความถูกต้องของข้อมูล : การทำงานของทรานแซกชันไม่ว่าจะสำเร็จหรือล้มเหลว ข้อมูลจะต้องสอดคล้องกันเสมอ
3. Isolation คือ การทำงานที่เป็นอิสระแกกัน : การทำงานของทรานแซกซันแต่ละทรานแซกชันจะเป็นอิสระจากกัน ข้อมูลที่ถูกปรับปรุงในทรานแซกชันหนึ่งจะไม่มีผลกันอีกทรานแซกชันหนึ่ง
4. Durability คือ ความคงอยู่ : ข้อมูลทั้งหมดจะคงอยู่หลังจากผ่านการคอมมิตทรานแซกชันแล้ว (commit transaction) ไม่ว่าจะเกิดเหตุการณ์ ระเบิดภูเขา เผากระท่อม หรืออื่น ๆ ก็ตาม

ตัวอย่าง การเขียนคำสั่งจัดการ Transaction ด้วยภาษา VB.Net


ให้ทำการสร้างฐานข้อมูลภายใต้ SQL Server 2008 และตารางข้อมูล พร้อมทั้งเพิ่มข้อมูลเข้าสู่ตาราง ดังนี้ (เปิดหน้าต่าง New Query ใน SQL Server 2008 แล้วป้อนคำสั่งตามตัวอย่างด้านล่าง)

CREATE DATABASE myDATA
GO

CREATE TABLE tblBankAccount (
          [ACC_NO] [varchar](10) NOT NULL PRIMARY KEY,
          [ACC_NAME] [varchar](50) NULL,
          [AMOUNT] [money])
GO

INSERT INTO tblBankAccount (ACC_NO,ACC_NAME,AMOUNT) 
                               VALUES('111','Kasem',50000)
INSERT INTO tblBankAccount (ACC_NO,ACC_NAME,AMOUNT) 
                               VALUES('222','Mesak',100)

ทำการเขียนโปรแกรมด้วย VB.Net

1. เปิด Visual Studio 20xx จากนั้นคลิกเลือก New Project....
เลือก Visual Basic -> Windows -> Windows Forms Application
ที่ช่อง Name ป้อน  myTransaction
จากนั้นคลิกปุ่ม OK

2. ที่ฟอร์ม ให้เพิ่มคอนโทร Button1 และ DataGridView ตามตัวอย่าง ดังภาพ

















3. ให้ดับเบิลคลิกที่ฟอร์ม หรือ ปุ่ม Button1 แล้วป้อนคำสั่ง ดังนี้

Imports System.Data
Imports System.Data.SqlClient

Public Class Form1
    Dim strConn As String = "Data Source=.\SQLEXPRESS;Initial Catalog=myData;Integrated Security=SSPI;"
    'Data Source เปลี่ยนตามเครื่องที่ติดต่อ
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Button1.Text = "คลิกเพื่อปรับปรุงยอดโอนเงิน"
        Button1.Width = 200
        DisplayData()
    End Sub
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Using objCS = New SqlConnection(strConn)
            objCS.Open()
            'คำสั่งจัดการ Transaction 
            Dim nTR As SqlTransaction
            nTR = objCS.BeginTransaction
            Try
                'ปรับปรุงข้อมูลชุดแรก ภายใต้ทรานแซกชัน nTR
                Dim strSQL1 As String = "UPDATE tblBankAccount SET Amount = Amount - 100 WHERE Acc_no = '111'"
                Dim objSQL1 As New SqlCommand(strSQL1, objCS, nTR)
                objSQL1.ExecuteNonQuery()

                'ปรับปรุงข้อมูลชุดที่สอง ภายใต้ทรานแซกชัน nTR
                Dim strSQL2 As String = "UPDATE tblBankAccount SET Amount = Amount + 100 WHERE Acc_no = '222'"
                Dim objSQL2 As New SqlCommand(strSQL2, objCS, nTR)
                objSQL2.ExecuteNonQuery()

                'เมื่อข้อมูลถูกปรับปรุงทั้งหมดเรียบร้อยแล้วทำการ คอมมิตทรานแซกชัน
                nTR.Commit()
            Catch ex As Exception
                'หากเกิดข้อผิดพลาก ให้ทำการโรลแบ็ก 
                nTR.Rollback()
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK)
            End Try
        End Using
        DisplayData()
    End Sub

    Sub DisplayData()
        ' นำข้อมูลจากตาราง tblBankAccount มาแสดงในกริด
        Using objCS = New SqlConnection(strConn)
            Dim objDS As New DataSet()
            Dim objDA = New SqlDataAdapter()
            objDA.SelectCommand = New SqlCommand("SELECT * FROM tblBankAccount", objCS)
            objDS.Clear()
            objDA.Fill(objDS, "tblBankAccount")
            DataGridView1.DataSource = objDS.Tables(0)
        End Using
    End Sub

End Class


4. จากนั้นกดปุ่ม F5 เพื่อทำการ Run แล้วลองทดสอบ ตามภาพ



















ข้อควรระวัง การใช้ทรานแซกชันระบบฐานข้อมูลจะทำการล็อกตารางที่อยู่ภายใต้ทรานแซกชัน ดังนั้นเวลาใช้ควรทำให้เสร็จในคราวเดียวกัน อย่าเปิดทรานแซกชันค้างไว้ โดยไม่ทำการ commit หรือ rollback

ขอส่งกำลังใจให้กับทหารกล้า ที่ปกป้องประเทศ ทุก ๆ ท่าน

03 กุมภาพันธ์ 2554

VB.Net Google Translator

Google ได้ทำการวิจัยและผลิตผลงานออกมาให้เราใช้งานอย่างมากมาย แถมยังได้สร้าง API สำหรับผลงานที่ผลิตขึ้นมาซึ่งมีมากมาย สำหรับบทความนี้ก็จะยกตัวอย่าง API ของตัวแปลภาษา (Google Translate) ซึ่งใช้แปลภาษาต่าง ๆ  เพื่อให้เราทั้งหลายนำไปเขียนโปรแกรมต่อยอด ซึ่งก็ไม่มีอะไซับซ้อน

Download API ของ Google Translate 
เราต้องเข้าไปทำการดาวน์โหลด API มาเก็บไว้ที่เครื่องเราก่อน ที่เว็บไซต์ http://code.google.com/p/google-api-for-dotnet/downloads/list จะมี API ให้เลือกหลายรุ่น แนะนำให้ download ไฟล์ชื่อ 
GoogleTranslateAPI_0.4_alpha.zip
จากนั้นทำการแตกไฟล์ ออกมาไว้ที่ floder ที่ต้องการ (แล้วจำไว้ด้วยว่าเก็บไว้ที่ไหน)


เขียนโปรแกรมด้วย VB.Net
1. เปิด Visual Studio 20xx จากนั้นคลิกเลือก New Project....
เลือก Visual Basic -> Windows -> Windows Forms Application
ที่ช่อง Name ป้อน  GooPlae  (อ่านว่า กูแปล)
จากนั้นคลิกปุ่ม OK

2. ทำการ Add Reference โดยไปที่เมนู Project -> Add Reference....
ที่หน้าต่าง Add Reference ให้คลิกที่แทป  Browse
แล้วเลือก GoogleTranslateAPI.dll ที่เรา Download  และทำการ Unzipไว้ตอนแรก
(จะเก็บอยู่ภายใต้ Floder ที่เรา Unzip จะอยู่ที่ bin -> DotNet)




















3. ที่ Form1 ให้เพิ่มคอนโทรล ลงในฟอร์ม ดังภาพ

 4. ทำการเขียนคำสั่ง โดย double click ที่ฟอร์ม แล้วป้อนคำสั่งดังนี้


Imports Google.API.Translate
Imports System.Data

Public Class Form1
    Private gooplae1 As New TranslateClient("")
    Private dt As New Data.DataTable("FromCountry")
    Private dt1 As New Data.DataTable("ToCountry")


    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        dt.Columns.Add("CountryCode", GetType(System.String))
        dt.Columns.Add("CountryName", GetType(System.String))

        dt.Rows.Add(New Object() {"af", "AFRIKAANS"})
        dt.Rows.Add(New Object() {"sq", "ALBANIAN"})
        dt.Rows.Add(New Object() {"am", "AMHARIC"})
        dt.Rows.Add(New Object() {"ar", "ARABIC"})
        dt.Rows.Add(New Object() {"hy", "ARMENIAN"})
        dt.Rows.Add(New Object() {"az", "AZERBAIJANI"})
        dt.Rows.Add(New Object() {"eu", "BASQUE"})
        dt.Rows.Add(New Object() {"be", "BELARUSIAN"})
        dt.Rows.Add(New Object() {"bn", "BENGALI"})
        dt.Rows.Add(New Object() {"bh", "BIHARI"})
        dt.Rows.Add(New Object() {"br", "BRETON"})
        dt.Rows.Add(New Object() {"bg", "BULGARIAN"})
        dt.Rows.Add(New Object() {"my", "BURMESE"})
        dt.Rows.Add(New Object() {"ca", "CATALAN"})
        dt.Rows.Add(New Object() {"chr", "CHEROKEE"})
        dt.Rows.Add(New Object() {"zh", "CHINESE"})
        dt.Rows.Add(New Object() {"zh-CN", "CHINESE_SIMPLIFIED"})
        dt.Rows.Add(New Object() {"zh-TW", "CHINESE_TRADITIONAL"})
        dt.Rows.Add(New Object() {"co", "CORSICAN"})
        dt.Rows.Add(New Object() {"hr", "CROATIAN"})
        dt.Rows.Add(New Object() {"cs","CZECH"})
        dt.Rows.Add(New Object() {"dv", "DHIVEHI"})
        dt.Rows.Add(New Object() {"nl", "DUTCH"})
        dt.Rows.Add(New Object() {"en", "ENGLISH"})
        dt.Rows.Add(New Object() {"eo", "ESPERANTO"})
        dt.Rows.Add(New Object() {"et", "ESTONIAN"})
        dt.Rows.Add(New Object() {"fo", "FAROESE"})
        dt.Rows.Add(New Object() {"tl", "FILIPINO"})
        dt.Rows.Add(New Object() {"fi", "FINNISH"})
        dt.Rows.Add(New Object() {"fr", "FRENCH"})
        dt.Rows.Add(New Object() {"fy", "FRISIAN"})
        dt.Rows.Add(New Object() {"gl", "GALICIAN"})
        dt.Rows.Add(New Object() {"ka", "GEORGIAN"})
        dt.Rows.Add(New Object() {"de", "GERMAN"})
        dt.Rows.Add(New Object() {"el", "GREEK"})
        dt.Rows.Add(New Object() {"gu", "GUJARATI"})
        dt.Rows.Add(New Object() {"ht", "HAITIAN_CREOLE"})
        dt.Rows.Add(New Object() {"iw", "HEBREW"})
        dt.Rows.Add(New Object() {"hi", "HINDI"})
        dt.Rows.Add(New Object() {"hu", "HUNGARIAN"})
        dt.Rows.Add(New Object() {"is", "ICELANDIC"})
        dt.Rows.Add(New Object() {"id", "INDONESIAN"})
        dt.Rows.Add(New Object() {"iu", "INUKTITUT"})
        dt.Rows.Add(New Object() {"ga", "IRISH"})
        dt.Rows.Add(New Object() {"it", "ITALIAN"})
        dt.Rows.Add(New Object() {"ja", "JAPANESE"})
        dt.Rows.Add(New Object() {"jw", "JAVANESE"})
        dt.Rows.Add(New Object() {"kn", "KANNADA"})
        dt.Rows.Add(New Object() {"kk", "KAZAKH"})
        dt.Rows.Add(New Object() {"km", "KHMER"})
        dt.Rows.Add(New Object() {"ko", "KOREAN"})
        dt.Rows.Add(New Object() {"ku", "KURDISH"})
        dt.Rows.Add(New Object() {"ky", "KYRGYZ"})
        dt.Rows.Add(New Object() {"lo", "LAO"})
        dt.Rows.Add(New Object() {"la", "LATIN"})
        dt.Rows.Add(New Object() {"lv", "LATVIAN"})
        dt.Rows.Add(New Object() {"lt", "LITHUANIAN"})
        dt.Rows.Add(New Object() {"lb", "LUXEMBOURGISH"})
        dt.Rows.Add(New Object() {"mk", "MACEDONIAN"})
        dt.Rows.Add(New Object() {"ms", "MALAY"})
        dt.Rows.Add(New Object() {"ml", "MALAYALAM"})
        dt.Rows.Add(New Object() {"mt", "MALTESE"})
        dt.Rows.Add(New Object() {"mi", "MAORI"})
        dt.Rows.Add(New Object() {"mr", "MARATHI"})
        dt.Rows.Add(New Object() {"mn", "MONGOLIAN"})
        dt.Rows.Add(New Object() {"ne", "NEPALI"})
        dt.Rows.Add(New Object() {"no", "NORWEGIAN"})
        dt.Rows.Add(New Object() {"oc", "OCCITAN"})
        dt.Rows.Add(New Object() {"or", "ORIYA"})
        dt.Rows.Add(New Object() {"ps", "PASHTO"})
        dt.Rows.Add(New Object() {"fa", "PERSIAN"})
        dt.Rows.Add(New Object() {"pl", "POLISH"})
        dt.Rows.Add(New Object() {"pt", "PORTUGUESE"})
        dt.Rows.Add(New Object() {"pt-PT", "PORTUGUESE_PORTUGAL"})
        dt.Rows.Add(New Object() {"pa", "PUNJABI"})
        dt.Rows.Add(New Object() {"qu", "QUECHUA"})
        dt.Rows.Add(New Object() {"ro", "ROMANIAN"})
        dt.Rows.Add(New Object() {"ru", "RUSSIAN"})
        dt.Rows.Add(New Object() {"sa", "SANSKRIT"})
        dt.Rows.Add(New Object() {"gd", "SCOTS_GAELIC"})
        dt.Rows.Add(New Object() {"sr", "SERBIAN"})
        dt.Rows.Add(New Object() {"sd", "SINDHI"})
        dt.Rows.Add(New Object() {"si", "SINHALESE"})
        dt.Rows.Add(New Object() {"sk", "SLOVAK"})
        dt.Rows.Add(New Object() {"sl", "SLOVENIAN"})
        dt.Rows.Add(New Object() {"es", "SPANISH"})
        dt.Rows.Add(New Object() {"su", "SUNDANESE"})
        dt.Rows.Add(New Object() {"sw", "SWAHILI"})
        dt.Rows.Add(New Object() {"sv", "SWEDISH"})
        dt.Rows.Add(New Object() {"syr", "SYRIAC"})
        dt.Rows.Add(New Object() {"tg", "TAJIK"})
        dt.Rows.Add(New Object() {"ta", "TAMIL"})
        dt.Rows.Add(New Object() {"tt", "TATAR"})
        dt.Rows.Add(New Object() {"te", "TELUGU"})
        dt.Rows.Add(New Object() {"th", "THAI"})
        dt.Rows.Add(New Object() {"bo", "TIBETAN"})
        dt.Rows.Add(New Object() {"to", "TONGA"})
        dt.Rows.Add(New Object() {"tr", "TURKISH"})
        dt.Rows.Add(New Object() {"uk", "UKRAINIAN"})
        dt.Rows.Add(New Object() {"ur", "URDU"})
        dt.Rows.Add(New Object() {"uz", "UZBEK"})
        dt.Rows.Add(New Object() {"ug", "UIGHUR"})
        dt.Rows.Add(New Object() {"vi", "VIETNAMESE"})
        dt.Rows.Add(New Object() {"cy", "WELSH"})
        dt.Rows.Add(New Object() {"yi", "YIDDISH"})
        dt.Rows.Add(New Object() {"yo", "YORUBA"})


        With ComboBox1
            .DataSource = dt
            .DisplayMember = "CountryName"
            .ValueMember = "CountryCode"
            .SelectedValue = "en"
        End With

        dt1 = dt.Copy()   ' Copy DataTable

        With ComboBox2
            .DataSource = dt1
            .DisplayMember = "CountryName"
            .ValueMember = "CountryCode"
            .SelectedValue = "th"
        End With

    End Sub
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        If TextBox1.Text = "" Then
            MessageBox.Show("Please Enter text", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
            TextBox1.Focus()
            Return
        End If
        Try
            TextBox2.Text = gooplae1.Translate(TextBox1.Text, ComboBox1.SelectedValue, ComboBox2.SelectedValue)
        Catch ex As Exception
            MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
        End Try

    End Sub
End Class 
 
5. จากนั้นทำการ run โปรแกรมโดยกดปุ่ม F5 แล้วทดสอบการแปล

























หมายเหตุ ในการแปลของ Google Translate จำเป็นต้องเข้าสู่ระบบอินเตอร์เน็ตก่อนทุกครั้ง

ตรุษจีน รวย รวย วันตรุษจีน มีทุกปี รวย ทุกปี

ชอบบทความ อย่าลืมคลิกโฆษณา


21 มกราคม 2554

VB.Net WMI สร้างคลาสแสดงรายละเอียดของคอมพิวเตอร์กับ WIN32

WMI หรือ Windows Management Instrumentation เป็นตัวจัดการโครงสร้างข้อมูลพื้นฐานและการดำเนินงานต่าง ๆ ภายใต้ระบบบฎิบัติการวินโดวส์ หรือเรียกง่ายๆ มันคือคลาสที่ใช้จัดการทุกเรื่องของวินโดวส์ สำหรับบทความนี้จะนำเสนอเสี้ยวหนึ่งของ WMI ที่เกี่ยวข้องกับ WIN32 โดยจะยกตัวอย่างโปรแกรม แสดงรายละเอียดต่าง ๆ ของระบบปฎิบัติการ และคอมพิวเตอร์ (hardware)
1. เปิด Visual Studio 20xx จากนั้นคลิกเลือก New Project....
เลือก Visual Basic -> Windows -> Windows Forms Application
ที่ช่อง Name ป้อน mySysInfo
2. จากนั้นให้เพิ่มคอนโทรล Button กับ Textbox ลงใน Form1 ดังภาพ















3. จากนั้นทำการเพิ่ม Reference สำหรับ WMI โดยไปที่เมนู Project -> Add Reference...
จะปรากฎหน้าจอดังภาพด้านล่าง

















ให้เลือก System.Management แล้วคลิกปุ่ม OK

4. ทำการสร้างคลาส โดยไปที่เมนู Project -> Add New Item...จากนั้นคลิกเลือก Class ที่ช่อง Name ป้อนชื่อโปรแกรม myWMI.vb















5. ที่หน้าจอเขียนโปรแกรม myWMI.vb ให้ป้อนคำสั่งตามตัวอย่างด้านล่าง

Imports System.Management

Public Class myWMI
    Private objOS As ManagementObjectSearcher
    Private objCS As ManagementObjectSearcher
    Private m_strComputerName As String
    Private m_strManufacturer As String
    Private m_StrModel As String
    Private m_strOSName As String
    Private m_strOSVersion As String
    Private m_strSystemType As String
    Private m_strTPM As String
    Private m_strWindowsDir As String

    Public Sub New()
        Dim objMgmt As ManagementObject
        objOS = New ManagementObjectSearcher("SELECT * FROM Win32_OperatingSystem")
        objCS = New ManagementObjectSearcher("SELECT * FROM Win32_ComputerSystem")
        For Each objMgmt In objOS.Get
            m_strOSName = objMgmt("name").ToString()
            m_strOSVersion = objMgmt("version").ToString()
            m_strComputerName = objMgmt("csname").ToString()
            m_strWindowsDir = objMgmt("windowsdirectory").ToString()
        Next

        For Each objMgmt In objCS.Get
            m_strManufacturer = objMgmt("manufacturer").ToString()
            m_StrModel = objMgmt("model").ToString()
            m_strSystemType = objMgmt("systemtype").ToString
            m_strTPM = objMgmt("totalphysicalmemory").ToString()
        Next
    End Sub
    Public ReadOnly Property ComputerName()
        Get
            ComputerName = m_strComputerName
        End Get

    End Property
    Public ReadOnly Property Manufacturer()
        Get
            Manufacturer = m_strManufacturer
        End Get

    End Property
    Public ReadOnly Property Model()
        Get
            Model = m_StrModel
        End Get

    End Property
    Public ReadOnly Property OsName()
        Get
            OsName = m_strOSName
        End Get

    End Property

    Public ReadOnly Property OSVersion()
        Get
            OSVersion = m_strOSVersion
        End Get

    End Property
    Public ReadOnly Property SystemType()
        Get
            SystemType = m_strSystemType
        End Get

    End Property
    Public ReadOnly Property TotalPhysicalMemory()
        Get
            TotalPhysicalMemory = m_strTPM
        End Get

    End Property

    Public ReadOnly Property WindowsDirectory()
        Get
            WindowsDirectory = m_strWindowsDir
        End Get
    End Property
End Class


6. จากนั้นย้อนกลับไปยังหน้าจอ Form1 ให้ Double Click ที่ปุ่ม Button1 เพื่อเข้าไปเขียนคำสั่ง จากนั้นให้ป้อนคำสั่งดังนี้

Public Class Form1

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim SHOW_SPEC As New myWMI
        With SHOW_SPEC
            TextBox1.Text = "COMPUTER NAME : " & .ComputerName & vbCrLf & _
                            "MODEL : " & .Model & vbCrLf & _
                            "MANUFACTURER : " & .Manufacturer & vbCrLf & _
                            "SYSTEM TYPE : " & .SystemType & vbCrLf & _
                            "OS : " & .OsName & vbCrLf & _
                            "OS VERSION : " & .OSVersion & vbCrLf & _
                            "WINDOWS DIRECTORY : " & .WindowsDirectory & vbCrLf & _
                            "TOTAL MEMORY : " & .TotalPhysicalMemory
        End With
    End Sub

End Class

7. ทำการบันทึกแล้วกดปุ่ม F5 เพื่อสั่งรันโปรแกรม จะปรากฎฟอร์ม ให้คลิกปุ่ม Button1 จะแสดงรายละเอียดของเครื่องลักษณะดังภาพ














จริง ๆ รายละเอียดต่าง ๆ ที่แสดงอยู่ ยังไม่หมดเพียงเท่านี้ ผู้อ่านสามารถแสดงสิ่งต่าง ๆ ได้อีกมากมาย อยากรู้ให้คลิกเข้าไปดูที่  WMI Classes -> Win32 Classes
http://msdn.microsoft.com/en-us/library/aa394084%28v=VS.85%29.aspx





















... อย่าเพิ่งเกาหัว และก็อย่าเพิ่งถามว่า แล้วจะใช้อย่างไร.... คำตอบมีอยู่ด้านล่างนี้แหละ

ย้อนกลับไปข้อ 5 ยังจำได้ไหมว่าเราได้สร้างคลาส myWMI.vb  ดังนี้

Imports System.Management

Public Class myWMI
    Private objOS As ManagementObjectSearcher    ' ตัวแปร objOS สำหรับเก็บค่า OS
 ....

มีการสร้าง ตัวแปร property ด้วยคำสั่ง

    Private m_strComputerName As String    ' ตัวแปรสำหรับใช้ใน proerty ชือ ComputerName
    Private m_strManufacturer As String        ' ตัวแปรสำหรับใช้ใน proerty ชือ Manufacturer
 .....

แล้วก็สร้าง property แบบ อ่านได้อย่างเดียวตามตัวแปรที่กำหนด

    Public ReadOnly Property ComputerName()
        Get
            ComputerName = m_strComputerName   ' ตัวแปร property ที่กำหนดไว้ก่อนหน้า
        End Get
    End Property

    Public ReadOnly Property Manufacturer()
        Get
            Manufacturer = m_strManufacturer           ' ตัวแปร property ที่กำหนดไว้ก่อนหน้า
        End Get
    End Property

จากนั้นมีการสร้าง Constructors เพื่ออ่านค่าของ WIN32 Class ที่เราต้องการ เช่น คลาส Win32_OperatingSystem
??? แล้ว Constructors มันคืออะไร มันคือ Sub New() .... End Sub
??? แล้ว Constructors เอาไว้ทำอะไร  Sub New จะทำงานเองโดยอัตโนมัติเมื่อมีการสร้างวัตถุขึ้นมาจากคลาส เช่น

Dim SHOW_SPEC As New myWMI

จากคำสั่งข้างต้น Sub New()....End Sub หรือ Constructors มันจะทำงานอัตโนมัติ (ถ้ามองให้ดี ๆ คล้าย ๆ กับ Form -> Load ที่เกิดขึ้นอัตโนมัติตอนเปิดฟอร์ม)

ดังนั้น เมื่อเราต้องการดึงค่า WIN32_OperatingSystem หรือค่า WIN32 อื่น ๆ เราจึงต้องทำใน Constructors นี้ .... เข้าใจหรือยังครับ....

จากตัวอย่าง

    Public Sub New()
        Dim objMgmt As ManagementObject
        objOS = New ManagementObjectSearcher("SELECT * FROM Win32_OperatingSystem")
        objCS = New ManagementObjectSearcher("SELECT * FROM Win32_ComputerSystem")
        For Each objMgmt In objOS.Get
            m_strOSName = objMgmt("name").ToString()
            m_strOSVersion = objMgmt("version").ToString()
            m_strComputerName = objMgmt("csname").ToString()
            m_strWindowsDir = objMgmt("windowsdirectory").ToString()
        Next
        .....
        .....
    End Sub

คำสั่งข้างต้นจะมีการอ่านค่าแล้วมาเก็บไว้ใน property ที่สร้างเตรียมไว้แล้ว

แล้ว SELECT * FROM Win32_OperatingSystem มาได้อย่างไร


จริงๆ มันคือการคิวรี ค่าจากคลาส Win32 ในส่วนของ OperatingSystem
แล้วถ้าเป็นคลาสอื่นล่ะจะไปหามาจากไหนได้อย่างไร

หาไม่ยาก ก็อยู่ใน MSDN ของ Microsoft ที่ผู้เขียนแสดงชื่อ web ไว้ให้แล้ว
เช่น เราต้องการดู BIOS จะทำอย่างไร ก็เข้าไปที่ MSDN ของ Microsoft ในส่วนของ Win32_BIOS

http://msdn.microsoft.com/en-us/library/aa394077%28v=VS.85%29.aspx

คลิกแล้วจะแสดงหน้าตาดังภาพ


























ถ้าเราต้องการดู SerialNumber ของ BIOS ตามลูกศรชี เราจะต้อง
1. สร้างตัวแปรสำหรับเก็บค่าของคิวรี SELECT ...
  
        Private objBIOS As ManagementObjectSearcher

    จากนั้นก็สั่งคิวรีข้อมูลจาก คลาส Win32_BIOS  ชื่อจะตรงกับคลาสที่เราเปิดดูใน MSDN

        objBIOS = New ManagementObjectSearcher("SELECT * FROM Win32_BIOS")

2. สร้างตัวแปร property ดังนี้
     
       Private m_strBIOSSerialNumber As String    ' ประเภทของข้อมูลต้องตรงกัน

3. อ่านค่าจาก objBIOS ซึ่งได้คิวรีข้อมูลมาจาก Win32_BIOS

        For Each objMgmt In objBIOS.Get
            m_strBIOSSerialNumber = objMgmt("SerialNumber").ToString()
        Next
        ' SerialNumber ชื่อจะตรงกับค่าที่แสดงอยู่ใน MSDN

4. สร้าง property ดังนี้

    Public ReadOnly Property BIOSSerialNumber()
        Get
            BIOSSerialNumber = m_strBIOSSerialNumber
        End Get
    End Property

มาถึงตรงนี้เราคงได้วิธีทำอะไรอื่น ๆ อีกมากมาย
ถ้าอยากรู้ Serial Number ของ Harddisk ก็ไม่ยากแล้วใช่หรือไม่ ....

อยากรู้อะไร WIN32 ทำได้หมด ถามถึงหวย ก็บอกได้จะเอาเบอร์อะไร


:-p

07 มกราคม 2554

VB.Net Game BINGO พูดได้นะจะบอกให้

Game BINGO เป็นตัวอย่างของโปรเจกต์ ที่ผู้เขียนไม่ได้ตั้งใจนำเสนอการเขียนเกมส์หรอก จริง ๆ ต้องการนำเสนอวิธีการสร้างออปเจกต์ ขณะรันโปรแกรม (Runtime) ซึ่งปกติเราจะใช้วิธีลาก คอนโทรลของ .Net มาวาง ๆ ๆ บนฟอร์มที่เราสร้างขึ้น
แต่ในบางครั้งเราจำเป็นต้องสร้างออปเจกต์ แบบอัตโนมัติ พร้อมทั้งสามารถเชื่อมโยงไปยัง เหตุการณ์ (event) ที่เราต้องการ โดยผ่านคำสั่ง เช่น
AddHandler btnNew.MouseClick, AddressOf btnNew_Click
แล้วก็มีเรื่องของการอ้าง property ในแบบอาศัยตัวแปรแทนชื่อที่กำหนดไว้ เช่น
Me.Controls("Label" & RandomNumber.ToString).Enabled = False
แถมด้วย คำสั่งที่ใช้ออกเสียงภาษาอังกฤษ โดยอาศัย API ชื่อ SAPI (S น่าจะมาจาก Speech  + กับ API) มาช่วย
และอื่น ๆ อีกมากมายจากโค้ดตัวอย่างต่อไปนี้ ลองทำดู แล้วจะรู้ว่าคุณทำได้

1. สร้าง Project เป็น Windows Form Application ขึ้นมา 1 ตัว ชื่อ BINGO ดังภาพด้านล่าง

















2. ที่ Form1 ให้ คลิกเมาส์ที่ฟอร์ม เร็ว ๆ สองที (double-click Mouse) จะเข้าสู่หน้าต่าง เขียนคำสั่ง ให้นำคำสั่งด้านล่างนี้ไปแทนที่ได้เลย
Public Class Form1
    Private lblNumber As New Label
    Private lblCounter As New Label
    Private btnRandom As New Button
    Private btnNew As New Button
    Private totLbl As Integer = 49
    Private aNewlbl(totLbl) As Label

    Private nTime As Integer = 0
    Private nCounter As Integer = 0

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        '
        'Form
        '
        Me.Text = "BINGO"
        Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
        Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
        Me.ClientSize = New System.Drawing.Size(653, 414)
        '
        'lblNumber
        '
        lblNumber.BackColor = System.Drawing.SystemColors.ActiveCaption
        lblNumber.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
        lblNumber.Font = New System.Drawing.Font("Microsoft Sans Serif", 72.0!, _
                                                                          System.Drawing.FontStyle.Bold, _
                                                                          System.Drawing.GraphicsUnit.Point, _
                                                                          CType(222, Byte))
        lblNumber.ForeColor = System.Drawing.Color.FromArgb(CType(CType(192, Byte), Integer), _
                                                                                          CType(CType(0, Byte), Integer), _
                                                                                          CType(CType(0, Byte), Integer))
        lblNumber.Location = New System.Drawing.Point(10, 272)
        lblNumber.Name = "lblNumber"
        lblNumber.Size = New System.Drawing.Size(490, 106)
        lblNumber.Text = "B I N G O"
        lblNumber.TextAlign = System.Drawing.ContentAlignment.MiddleCenter
        Me.Controls.Add(lblNumber)
        '
        'lblCounter
        '
        lblCounter.BackColor = System.Drawing.SystemColors.ActiveCaption
        lblCounter.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
        lblCounter.Font = New System.Drawing.Font("Microsoft Sans Serif", 36.0!, _
                                                                          System.Drawing.FontStyle.Bold, _
                                                                          System.Drawing.GraphicsUnit.Point, _
                                                                          CType(222, Byte))
        lblCounter.ForeColor = System.Drawing.Color.FromArgb(CType(CType(192, Byte), Integer), _
                                                                                          CType(CType(0, Byte), Integer), _
                                                                                          CType(CType(0, Byte), Integer))
        lblCounter.Location = New System.Drawing.Point(522, 272)
        lblCounter.Name = "lblCounter"
        lblCounter.Size = New System.Drawing.Size(109, 63)
        lblCounter.TextAlign = System.Drawing.ContentAlignment.MiddleCenter
        Me.Controls.Add(lblCounter)
        '
        'btnRandom
        '
        btnRandom.Font = New System.Drawing.Font("Microsoft Sans Serif", 16.0!, _
                                                                            System.Drawing.FontStyle.Regular, _
                                                                            System.Drawing.GraphicsUnit.Point, _
                                                                            CType(222, Byte))
        btnRandom.Location = New System.Drawing.Point(508, 18)
        btnRandom.Name = "btnRandom"
        btnRandom.Size = New System.Drawing.Size(137, 39)
        btnRandom.Text = "Random"
        btnRandom.UseVisualStyleBackColor = True
        AddHandler btnRandom.MouseClick, AddressOf btnRandom_Click
        Me.Controls.Add(btnRandom)
        '
        'btnNew
        '
        btnNew.Font = New System.Drawing.Font("Microsoft Sans Serif", 16.0!, _
                                                                      System.Drawing.FontStyle.Regular, _
                                                                      System.Drawing.GraphicsUnit.Point, _
                                                                      CType(222, Byte))
        btnNew.Location = New System.Drawing.Point(508, 67)
        btnNew.Name = "Button2"
        btnNew.Size = New System.Drawing.Size(137, 39)
        btnNew.Text = "New Game"
        btnNew.UseVisualStyleBackColor = True
        AddHandler btnNew.MouseClick, AddressOf btnNew_Click
        Me.Controls.Add(btnNew)
        '
        'Label
        '
        Dim tt As Integer = 10
        For i As Integer = 0 To totLbl
              aNewlbl(i) = New Label With {.Name = "Label" & CType(i + 1, String).Trim, _
                                                         .Text = CType(i + 1, String).Trim, _
                                                         .Location = New Point(CType(((i Mod 10) * 50) + 10, Integer), CType(tt, Integer)), _
                                                         .Size = New Size(40, 40), _
                                                         .Font = New System.Drawing.Font("Microsoft Sans Serif", _ 
16.0!, System.Drawing.FontStyle.Bold, _
                                                                    System.Drawing.GraphicsUnit.Point, _
                                                                    CType(222, Byte)), _
                                                         .TextAlign = System.Drawing.ContentAlignment.MiddleCenter, _
                                                         .BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle, _
                                                         .BackColor = Color.Azure}
            If i Mod 10 = 9 Then
                tt = tt + 50
            End If
            Me.Controls.Add(aNewlbl(i))
        Next i
    End Sub

    Private Sub btnRandom_Click(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
        btnRandom.Enabled = False
        btnNew.Enabled = False
        nCounter = nCounter + 1
        RandomNumber()
        btnRandom.Enabled = True
        btnNew.Enabled = True
    End Sub

    Private Sub btnNew_Click(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
        'Reset
        nCounter = 0
        lblCounter.Text = ""
        lblNumber.Text = "B I N G O"
        For Each ctrl As Control In Me.Controls
             If TypeOf ctrl Is Label Then
                 If ctrl.Name <> "lblNumber" And ctrl.Name <> "lblCounter" Then
                      ctrl.BackColor = Color.Azure
                      ctrl.Enabled = True
                 End If
             End If
        Next
        PlaySound("lET'S START BINGO")
    End Sub

    Private Sub RandomNumber()
        Dim RandomClass As New Random()
        Dim RandomNumber As Integer
        If nCounter <= 50 Then            
             'Create a new Random class in VB.NET
             Do While True
                   RandomNumber = RandomClass.Next(1, 51)
                   If Me.Controls("Label" & RandomNumber.ToString).Enabled = True Then
                         Exit Do
                   End If
             Loop
        Else
             MessageBox.Show("Complete BINGO")
             Return
        End If
        lblCounter.Text = nCounter.ToString
        lblNumber.Text = RandomNumber.ToString
        PlaySound("Number " & lblNumber.Text)
        Me.Controls("Label" & RandomNumber.ToString).Enabled = False
        Me.Controls("Label" & RandomNumber.ToString).BackColor = Color.Red
        If nCounter >= 50 Then
              MessageBox.Show("B I N G O  Complete !!!!", "BINGO", MessageBoxButtons.OK, MessageBoxIcon.Information)
        End If
    End Sub

    Private Sub PlaySound(ByVal Word As String)
        Dim SAPI
        SAPI = CreateObject("SAPI.spvoice")
        SAPI.speak(Word)
    End Sub
End Class
 แล้วลอง Run โปรเจกต์ดู จะปรากรฎหน้าตาโปรแกรม คล้าย ๆ แบบนี้ ลองเล่นดู อิๆๆ
เผื่อเปิดโต๊ะแข่ง กับ Bingo ตามงานวัด

23 ธันวาคม 2553

VB.Net and C# Comparison

VB.Net and C# Comparison
-------------------------------
http://www.harding.edu/fmccown/vbnet_csharp_comparison.html


Java and C# Comparison
-----------------------------
http://www.harding.edu/fmccown/java_csharp_comparison.html


learn VB.NET and ASP.NET
------------------------------
http://idealprogrammer.com/
http://www.learnvisualstudio.net/

VB.Net สร้าง Form Login

หลังจากที่เราได้เรียนรู้การสร้างฟอร์มมาหลายรูปแบบ ในบทเรียนนี้ เราจะมาทำการเรียนรู้วิธีการสร้างฟอร์ม Login
ตัวอย่างในตอนนี้จะอาศัยฟอร์มที่เราได้สร้างไว้ในบทความก่อนหน้า ให้ผู้อ่านสร้างฟอร์มตามหัวข้อ
VB.Net จับ Form ใส่ SplitContainer ก่อน เพราะเราจะต้องนำเอาโปรเจกต์ที่ได้สร้างไว้มาต่อยอดทำฟอร์ม login (ใครยังไม่เคยทำรีบไปทำก่อนนะจะบอกให้)

หลังจากนั้นให้สร้างฐานข้อมูล และตารางที่ SQL Server 200x ดังนี้

USE [MYDATA]     --เราสร้างไว้ตั้งแต่หัวข้อ VB.Net One Table Data Entry
GO

CREATE TABLE [dbo].[tblUser](
[USER_ID] [varchar](15) NOT NULL,
[PASSWORD] [varchar](15) NOT NULL,
[USERNAME] [varchar](50) NULL,
CONSTRAINT [PK_tblUser] PRIMARY KEY CLUSTERED
(
[USER_ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF,
          IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON,
         ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

--ทำการเพิ่มข้อมูลภายใต้ SQL Server ดังนี้
INSERT INTO tblUSER VALUES('kasem','5555','Kasem Kamolchaipisit')
จากนั้นกลับมาที่ Visual Studio 20xx อีกครั้ง แล้วทำตามขั้นตอน ดังนี้
1. ให้กดปุ่ม Ctrl + Shift + A จากนั้นจะปรากฎ หน้าจอดังภาพ


- คลิกเลือก Windows Form
- ที่ช่อง Name ตั้งชื่อฟอร์ม : frmLogIn.vb
- คลิกปุ่ม Add

2. ที่ฟอร์ม frmLogIn ให้สร้างคอนโทรลต่าง ๆ ดังภาพ


กำหนด Property ของคอนโทรลต่าง ๆ ดังนี้
    หมายเลข 1 กำหนด
     (Name)           =   txtUser_ID
     MaxLength       =  15
         
   หมายเลข 2 กำหนด
     (Name)           =   txtPassword
     MaxLength       =  15
     PasswordChar  =  *

   หมายเลข 3 กำหนด
     (Name)           =   btnLogIn
   หมายเลข 4 กำหนด 
     (Name)           =   btnExit

3. ที่ฟอร์ม frmLogIn ให้ Double Click เมาส์ ที่ว่าง ๆ ของฟอร์ม เพื่อเปิดหน้าต่างเขียนโค้ดคำสั่ง
ให้เขียนคำสั่งดังนี้

Imports System.Data
Imports System.Data.SqlClient

Public Class frmLogIn
    Public pUser_id As String = ""
    Public pPassword As String = ""
    Private Sub btnLogIn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnLogIn.Click

        Dim queryString As String = "SELECT * FROM tblUser WHERE USER_ID = '" & txtUser_ID.Text & "'"

        Using connection = New SqlConnection("Data Source=.;Initial Catalog=MYDATA;Integrated Security=True")
            Dim command As New SqlCommand(queryString, connection)
            connection.Open()

            Dim reader As SqlDataReader = command.ExecuteReader()
            If reader.HasRows = 0 Then
                MessageBox.Show("Invalid User", "Message", MessageBoxButtons.OK, MessageBoxIcon.Error)
                txtUser_ID.Focus()
            Else
                reader.Read()
                pUser_id = reader("user_id")
                pPassword = reader("password")
                If txtPassword.Text.Trim = pPassword.Trim Then
                    Me.Hide()
                    ' Complete
                    Dim frm As New Form1()
                    frm.Show()
                Else
                    MessageBox.Show("Password not match", "Message", MessageBoxButtons.OK, MessageBoxIcon.Error)
                    txtPassword.Focus()
                End If
            End If
            reader.Close()
        End Using
    End Sub

    Private Sub btnExit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnExit.Click
        Me.Close()
    End Sub
End Class

เพิ่มเติม เนื่องจากฟอร์ม frmLogIn จะต้องถูกกำหนดให้เปิดเป็นฟอร์มแรก (startup form) ดังนั้นเราต้องไปกำหนด startup form ใหม่ โดยคลิกที่เมนู Project เลือก myFormSplitContainer Properties....
สำหรับ myFormSplitContainer คือชื่อ Project ที่เราสร้างไว้ตอนแรก ดังนั้นถ้าผู้อ่านตั้งชื่อเป็นอย่างอื่นชื่อนี้ก็จะเปลี่ยนไป



จากนั้นให้ไปเปิดฟอร์ม ชื่อ From1 ที่เราทำไว้ในหัวข้อ VB.Net จับ Form ใส่ SplitContainer แล้วเพิ่มคำสั่ง ดังนี้
    Private Sub Form1_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
        frmLogIn.Close()
    End Sub


การเพิ่มคำสั่งเพื่อเวลาเราปิดฟอร์ม Form1 แล้วให้ปิดฟอร์ม frmLogIn ด้วย ไม่อย่างนั้นโปรแกรมที่เราสร้างมาจะยังไม่ปิดตัวเองและยังคงค้างอยู่ใน memory

สวัสดี ได้ข่าวว่า "เหล้าหมาใจดำ" กำลังมาแรง แซง แบล๊กเลเบิ้ล

18 ธันวาคม 2553

VB.Net Web Camera

ตัวอย่าง การเขียนโปรแกรมติดต่อกับ Web Camera ด้วย VB.Net
ให้ออกแบบหน้าจอดังภาพ

















เขียนโค้ดคำสั่งดังนี้

Imports System
Imports System.IO
Imports System.Runtime.InteropServices
Imports Microsoft.Win32

Public Class Form1
Inherits System.Windows.Forms.Form

Const WM_CAP_START = &H400S
Const WS_CHILD = &H40000000
Const WS_VISIBLE = &H10000000

Const WM_CAP_DRIVER_CONNECT = WM_CAP_START + 10
Const WM_CAP_DRIVER_DISCONNECT = WM_CAP_START + 11
Const WM_CAP_EDIT_COPY = WM_CAP_START + 30
Const WM_CAP_SEQUENCE = WM_CAP_START + 62
Const WM_CAP_FILE_SAVEAS = WM_CAP_START + 23

Const WM_CAP_SET_SCALE = WM_CAP_START + 53
Const WM_CAP_SET_PREVIEWRATE = WM_CAP_START + 52
Const WM_CAP_SET_PREVIEW = WM_CAP_START + 50

Const SWP_NOMOVE = &H2S
Const SWP_NOSIZE = 1
Const SWP_NOZORDER = &H4S
Const HWND_BOTTOM = 1
'--The capGetDriverDescription function retrieves the version
' description of the capture driver--
Declare Function capGetDriverDescriptionA Lib "avicap32.dll" _
(ByVal wDriverIndex As Short, _
ByVal lpszName As String, ByVal cbName As Integer, _
ByVal lpszVer As String, _
ByVal cbVer As Integer) As Boolean

'--The capCreateCaptureWindow function creates a capture window--
Declare Function capCreateCaptureWindowA Lib "avicap32.dll" _
(ByVal lpszWindowName As String, ByVal dwStyle As Integer, _
ByVal x As Integer, ByVal y As Integer, ByVal nWidth As Integer, _
ByVal nHeight As Short, ByVal hWnd As Integer, _
ByVal nID As Integer) As Integer

'--This function sends the specified message to a window or windows--
Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
(ByVal hwnd As Integer, ByVal Msg As Integer, _
ByVal wParam As Integer, _
<MarshalAs(UnmanagedType.AsAny)> ByVal lParam As Object) As Integer

'--Sets the position of the window relative to the screen buffer--
Declare Function SetWindowPos Lib "user32" Alias "SetWindowPos" _
(ByVal hwnd As Integer, _
ByVal hWndInsertAfter As Integer, ByVal x As Integer, _
ByVal y As Integer, _
ByVal cx As Integer, ByVal cy As Integer, _
ByVal wFlags As Integer) As Integer

'--This function destroys the specified window--
Declare Function DestroyWindow Lib "user32" _
(ByVal hndw As Integer) As Boolean

'---used to identify the video source---
Dim CamSource As Integer
'---used as a window handle---
Dim hWnd As Integer

Private Sub cameraSource()
Dim DriverName As String = Space(80)
Dim DriverVersion As String = Space(80)
For i As Integer = 0 To 9
If capGetDriverDescriptionA(i, DriverName, 80, _
DriverVersion, 80) Then
ListBox1.Items.Add(DriverName.Trim)
End If
Next
End Sub
Private Sub previewCamera(ByVal pbCtrl As PictureBox)
hWnd = capCreateCaptureWindowA(CamSource, _
WS_VISIBLE Or WS_CHILD, 0, 0, 0, _
0, pbCtrl.Handle.ToInt32, 0)
If SendMessage( _
hWnd, WM_CAP_DRIVER_CONNECT, _
CamSource, 0) Then

'---set the preview scale---
SendMessage(hWnd, WM_CAP_SET_SCALE, True, 0)
'---set the preview rate (ms)---
SendMessage(hWnd, WM_CAP_SET_PREVIEWRATE, 30, 0)
'---start previewing the image---
SendMessage(hWnd, WM_CAP_SET_PREVIEW, True, 0)
'---resize window to fit in PictureBox control---
SetWindowPos(hWnd, HWND_BOTTOM, 0, 0, _
pbCtrl.Width, pbCtrl.Height, _
SWP_NOMOVE Or SWP_NOZORDER)
Else
'--error connecting to video source---
DestroyWindow(hWnd)
End If
End Sub
Private Sub stopPreviewCamera()
SendMessage(hWnd, WM_CAP_DRIVER_DISCONNECT, CamSource, 0)
DestroyWindow(hWnd)
End Sub

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
cameraSource()
btnPreview.Enabled = False
btnStopPreview.Enabled = False
btnRecord.Enabled = False
btnStopRecord.Enabled = False
btnCapture.Enabled = False
Me.PictureBox1.SizeMode = PictureBoxSizeMode.StretchImage
Me.SaveFileDialog1.FileName = "Kasem"
Me.SaveFileDialog1.Filter = "PNG|*.png"
End Sub

Private Sub ListBox1_DoubleClick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ListBox1.DoubleClick
Label1.Visible = False
previewCamera(PictureBox1)
btnStopPreview.Enabled = True
btnPreview.Enabled = False
btnRecord.Enabled = True
btnCapture.Enabled = True
End Sub

Private Sub ListBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ListBox1.SelectedIndexChanged
CamSource = ListBox1.SelectedIndex
'---preview the selected video source
End Sub
' recording
Private Sub btnRecord_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRecord.Click
btnStopRecord.Enabled = True
btnRecord.Enabled = False
SendMessage(hWnd, WM_CAP_SEQUENCE, 0, 0)
End Sub

' stop recording and ask to save video
Private Sub btnStopRecord_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStopRecord.Click
Dim save As Integer
save = MsgBox("Do you want to save your recording video", MsgBoxStyle.YesNo + MsgBoxStyle.Information, "Recording Video")
If (save = MsgBoxResult.Yes) Then
Dim saveName As New SaveFileDialog
saveName.Filter = "Avi file(*.avi)|*.avi"
If saveName.ShowDialog = DialogResult.OK Then
' SendMessage(hWnd, WM_CAP_FILE_SAVEAS, 0, "C:\RecordedVideo.avi")
SendMessage(hWnd, WM_CAP_FILE_SAVEAS, 0, saveName.FileName)
End If
End If
Me.Cursor = System.Windows.Forms.Cursors.Default
btnRecord.Enabled = True
btnStopRecord.Enabled = False
End Sub

' preview
Private Sub btnPreview_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPreview.Click
CamSource = ListBox1.SelectedIndex
previewCamera(PictureBox1)
btnPreview.Enabled = False
btnStopPreview.Enabled = True
End Sub

'stop preview
Private Sub btnStopPreview_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStopPreview.Click
stopPreviewCamera()
btnPreview.Enabled = True
btnStopPreview.Enabled = False
btnCapture.Enabled = False
End Sub

Private Sub btnCapture_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCapture.Click
Dim data As IDataObject
Dim bmap As Image
SendMessage(hWnd, WM_CAP_EDIT_COPY, 0, 0)
data = Clipboard.GetDataObject()
If data.GetDataPresent(GetType(System.Drawing.Bitmap)) Then
bmap = CType(data.GetData(GetType(System.Drawing.Bitmap)), Image)
Me.PictureBox1.Image = bmap
stopPreviewCamera()
Me.btnPreview.Enabled = True
If Me.SaveFileDialog1.ShowDialog = DialogResult.OK Then
bmap.Save(Me.SaveFileDialog1.FileName, Imaging.ImageFormat.Png)
End If

'If Me.SaveFileDialog1.ShowDialog = DialogResult.OK Then
' bmap.Save(Me.SaveFileDialog1.FileName, Imaging.ImageFormat.Bmp)
'End If

previewCamera(PictureBox1)
End If
End Sub

End Class

ขนมเข่ง

ขนมเข่ง กับ วันตรุษจีน
เกิดมาก็เจอกับขนมเข่ง เห็นขนมเข่งมากมายวางเรียงเต็มบ้าน เป็นแบบนี้ทุกปี จำไม่ได้ว่าเลิกทำไปตั้งแต่เมื่อไร สมัยเมื่อเป็นเด็ก ย้อนกลับไปเมื่อราว 30 กว่าปีก่อน พอใกล้ถึงวันตรุษจีนที่ไรที่บ้านจะมีการทำขนมเข่ง เพื่อนำไปแจก มีทั้งคนแถวบ้าน และก็ลูกค้า ซึ่งจะต้องเตรียมการกันก่อนโดยจะเริ่มทำกันก่อนวันตรุษจีนหลายวัน โดยมีป๊า(พ่อ)เป็นโต้โผใหญ่ ส่วนพวกเด็กเล็ก ๆ ก็เป็นลูกมือ ทำกันอย่างสนุกสนาน สมัยนั้นไม่สะดวกสบายเท่ากับสมัยนี้ เริ่มตั้งแต่ต้องไปหาซื้อข้าวเหนียว (ข้าวเหนียวที่ยังไม่ได้นึ่ง) จากนั้นพวกเราก็จะตามป๊าไปโรงทำขนมซึ่งอยู่ไม่ไกลจากบ้านซักเท่าไหร่ (ปัจจุบันโรงทำขนมเจ้านี้ไม่มีแล้ว) นำข้าวเหนียวไปโม่ให้กลายเป็นแป้ง โมหินจะมีลักษณะดังภาพ แต่สมััยนั้นดีหน่อย ติดมอเตอร์ ทำให้บดข้าวเหนียวให้เป็นแป้งได้ไว เวลาโมจะต้องใส่ข้าวเหนียวกับน้ำสะอาดเพื่อจะได้โมออกมาเป็นแป้ง แล้วก็มีถุงผ้าดิบรองรับไว้ เราจะเริ่มทำกันตอนกลางคืน ก็ใช้เวลาพักใหญ่ ๆ กว่าจะเสร็จ เมื่อเสร็จแล้วแป้งที่ได้ยังไม่สามารถนำมาทำขนมได้ ต้องทำให้น้ำที่ใช้ตอนโม่พร่องออกจากแป้งก่อน วิธีการที่ทำสมัยนั้นคือ ผูกถุงผ้าที่มีน้ำแป้งอยู่ แขวนไว้ที่ขือบ้าน 1 คืน พอวันรุ่งขึ้น แป้งไม่ได้แห้งสนิทซึ่งก็กำลังดี
จากนั้นป๊าก็จะนำเอากาละมัง (สมัยนั้นกาละมังจะเป็นอะลูมิเนียมใบใหญ่) นำแป้งข้าวเหนียวที่โม่เตรียมไว้ตั้งแต่เมื่อคืนมาใส่ สำหรับส่วนผสมการทำนอกจากแป้งข้าวเหนียวก็จะมี แป้งมัน กับน้ำตาลทรายขาว เราก็เริ่มเทน้ำตาลทรายขาวลงไป ป๊าก็จะคอยนวดแป้งซึ่งเปียกน้ำหมาด ๆ สักพักแป้งที่ผสมกับน้ำตาลก็เริ่มเหลว ระหว่างนั้นป๊าก็จะกวนไปชิมไป ว่าหวานพอดีหรือยัง (ไม่มีการตวงส่วนผสมใด ๆ ทั้งสิ้น) จนได้ที่ แล้วก็ใส่แป้งมัน (ใส่ไม่ต้องมาก) ตอนนั้นก็สงสัย เลยถามป๊าว่าใส่เพื่ออะไร ป๊าก็ตอบมาว่า เพื่อให้ขนมเหนียว นุ่ม ซึ่งก็เป็นจริง เพราะ พอถึงวันตรุษจีนทีไรหมดทุกที บางคนมาขอหรือจองก่อนวันแจกก็มี
หลังจากนวด กวน ผสมแป้งได้ที่แล้ว เหล่าลูกมือ ก็ต้องเตรียมเข่ง ซึ่งก็คือ กระทงใบตองแห้ง ซื้อมาเยอะมาก แล้วก็มีถ้วยรองเข่ง ซึ่งสมัยก่อนจะทำด้วยอะลูมิเนียม แต่ปัจจุบันเห็นเป็นไม่ไผ่สาน เราก็นำกระทงมาใส่ไว้ในถ้วยรองเข่ง แล้วก็วางเรียงกัน ส่วนคนอื่นก็ทำหน้าที่นำน้ำมันมะพร้าวมาทา (สมัยนั้นยังไม่มีน้ำมันพืชเป็นขวด ๆ แบบสมัยนี้) ทาเพื่อให้เข่งไม่ติดกับขนม จากนั้นพวกเราก็ทำการหยอดแป้งขนมเข่ง ลงในเข่งกันอย่างสนุกสนาน
ต่อมาต้องนำขนมไปนึ่ง การทำขนมเป็นจำนวนมากคงใช้เตาแก๊ส และซึ็งนึ่งแบบทำครัวตามบ้านคงไม่ทันกิน ที่บ้านก็จะมีกระทะใบใหญ่มาก ๆ เส้นผ่าศูนย์กลางเมตรนึงได้มั้ง พวกเราก็จะหาหินก้อนใหญ่ ๆ มาวางรองกระทะ แล้วก็ใช้ไม้เป็นเชื้อเพลิง เวลาทำก็จะใส่น้ำลงในกระทะ หาไม้มาขัดกันเป็นฐานวางขนม จากนั้นก็จะมีไม้ไผ่สานเป็นวงกลมใหญ่ ๆ เหมือนฝาปิดเข่งฝักมารองจากนั้นก็นำขนมเข่งมาเรียงกันจนเต็ม แล้วก็วางไม้ไผ่สาานวงกลมใหญ่ ๆ ซ้อนไป แล้ววางเข่งขนมไปเป็นชั้น ๆ สูงเกือบ 10 ชั้น จากนั้นก็นำฝาซึ้งยักษ์ สมัยนั้นต้องเรียกว่ายักษ์ เพราะตอนเด็ก ๆ เวลาเล่นซ่อนแอบก็จะเข้าไปแอบอยู่ในนี้ได้อย่างสบาย นำมาครอบขนมไว้เพื่อนึ่งขนมให้สุก
เวลานึงขนมก็จะมีเทคนิคในการนึ่ง โดยผู้เขียนจะเป็นคนคอยควบคุมเวลา สมัยนั้นคงไม่ต้องหานาฬิกาปลุกแบบสมัยนี้ วิธีการของเราก็คือ ใช้ธูป แทนนาฬิกาปลุก ก็ทำการจะธูป แล้วปักไว้ข้าง ๆ เตา เวลาคนเดินไปเดินมาหรือมาที่บ้านก็จะถามว่าจุดไว้บูชาขนมเหรอ เราก็แกล้งตอบว่าใช่ จะให้ขนมอร่อยก็ต้องบูชาขนม แต่จริง ๆ แล้ว มันคือนาฬิกาจับเวลา เวลานึ่งเราก็คอยดูน้ำอย่าให้น้ำแห้งจากกระทะ แล้วก็ดูธูปว่าหมดหรือยัง รอจนธูปหมด พอหมด + อีกสัก 5 นาทีก็นำขนมขึ้นจากเตาได้เลย ขนมก็สุกเรียบร้อย หอมน่ากิน
แต่ยังไม่หมดแค่นั้น เราก็ต้องยกขนมออกมาจากเตา เอาออกจากถ้วย มาเรียงต่อ ๆ กัน แล้วก็นำขนมไปนึ่งต่อ การนึ่งครั้งใหม่ต้องเทน้ำที่นึ่งเก่าออกให้หมดแล้วใส่น้ำใหม่เข้าไปไม่งั้นขนมล๊อตใหม่จะสีเหลืองไม่น่ารับประทาน เราทำกันอย่างนี้กันทั้งวัน ๆ เลย ตั้งแต่เช้ายันมืด เคยนับขนมที่ทำได้ ปี ๆ นึงเป็นพันเข่ง เมื่อนึ่งขนมเสร็จ ขั้นตอนต่อมา ก็คือแต้มจุดสี ก็ไปนำสีผสมอาหารสีแดงมาผสมน้ำ แล้วก็นำตะเกียบมาจุ่มแล้วจิ้มลงบนขนม
ส่วนจะจิ้ม กี่จุดก็ตามสะดวก แรก ๆ สนุก จิ้ม สามจุด ไป ๆ เหลือจุดเดียว เพราะเมื่อย จุดสีมิได้บ่งบอกอะไรหรอกเพราะสมัยนั้นยังไม่มีขนมเข่งหน้ามะพร้าว หน้า ... จิปาถะเหมือนสมัยนี้
ขนมเข่งเป็นขนมที่ไม่หมดอายุง่ายๆ เก็บกันได้เป็นเดือน ๆ หลายครั้งที่ทำก็เก็บส่วนหนึ่งไว้กิน ด้วยความเบื่อมาก ๆ ไม่มีใครกินเลย คาไว้ในบ้านเป็นเดือน ๆ จนราขึ้น สมัยนั้นราไม่เป็นอัตราย ถ้าเป็นปานี้คงไม่มาเขียนบทความนี้ได้หรอก อิๆๆ เวลาหิวหาอะไรกินไม่ได้ก็ใช้ขนมเข่งนี่แหละ หลังจากที่เก็บไว้หลายเดือนลักษณะของขนมจะแข็งโป้กปาหัวแตกได้เลย เราก็ต้องเอาเข่งใบตองออก แล้วล้างน้ำเอาราที่ขึ้นออกให้หมด จากนั้นก็หามีดอีโต้ใหญ่ ๆ มาหั่นให้เป็นชิ้น ๆ บาง ๆ หน่อย แล้วนำขนมนั้นไปทอดกับน้ำมัน กินแสนอร่อย วันใดเจอไข่อยู่ในครัวก็เอาขนมเข่งมาชุบไข่ทอด อร่อยไปทั้งวัน
เวลาเลยมาหลายสิบปี เราก็ทำขนมกันเป็นสิบปี จนจำไม่ได้ว่าเราเลิกทำกันตอนไหน คงเป็นเพราะบ้านเมืองเจริญขึ้น ในกรุงเทพฯ จะหาที่จุดเตาใหญ่ ๆ เอาไม้มาทำฟืนคงยาก แล้วก็เลิกทำไปในที่สุด

ตรุษจีนนี้อย่าลืมหาขนมเข่งมากินสักเข่งน่ะ....

17 ธันวาคม 2553

VB.Net One Table Data Entry

ตัวอย่าง การเขียนโปรแกรมป้อนข้อมูลในลักษณะตารางเดียว ซึ่งมีทั้งการสอบถามข้อมูล การแสดงข้อมูล การเพิ่มข้อมูล การลบข้อมูล การแก้ไขข้อมูล และการลบข้อมูล อยู่ในหน้าจอเดียวกัน ตามตัวอย่างในภาพ





















ก่อนอื่นสร้างโปรเจกต์ใหม่ โดยตั้งชื่อว่า myAPP





สำหรับวิธีการใส่โค้ดภายใต้ Form1.Designer.vb ให้ทำดังนี้
(ทำเพื่อเราไม่ต้องมาลากวางคอนโทรลต่าง ๆ ตามรูปด้านบน)






















 ที่ Solution Explorer
      - คลิกที่ปุ่ม หมายเลข 1 Show All File
      - คลิกที่หมายเลข 2 เพื่อแสดงไฟล์ทั้งหมดของ Form1
      - ดับเบิ้ลคลิกที่ไฟล์หมายเลข 3 เพื่อเปิด Source Code ขึ้นมา

  จากนั้นนำโค้ดด้านล่างนี้ไปแทนที่โค้ดของเดิม

Source Code -> Form1.Designer.vb

<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class Form1
Inherits System.Windows.Forms.Form

'Form overrides dispose to clean up the component list.
<System.Diagnostics.DebuggerNonUserCode()> _
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub

'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer
'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
<System.Diagnostics.DebuggerStepThrough()> _
Private Sub InitializeComponent()
Me.txtStudent_ID = New System.Windows.Forms.TextBox()
Me.txtFirstName = New System.Windows.Forms.TextBox()
Me.txtLastName = New System.Windows.Forms.TextBox()
Me.Label1 = New System.Windows.Forms.Label()
Me.Label2 = New System.Windows.Forms.Label()
Me.Label3 = New System.Windows.Forms.Label()
Me.SplitContainer1 = New System.Windows.Forms.SplitContainer()
Me.Label4 = New System.Windows.Forms.Label()
Me.txtSearch = New System.Windows.Forms.TextBox()
Me.dg = New System.Windows.Forms.DataGridView()
Me.btnLast = New System.Windows.Forms.Button()
Me.btnFirst = New System.Windows.Forms.Button()
Me.btnDisplay = New System.Windows.Forms.Button()
Me.btnPrevious = New System.Windows.Forms.Button()
Me.btnNext = New System.Windows.Forms.Button()
Me.btnNew = New System.Windows.Forms.Button()
Me.btnDelete = New System.Windows.Forms.Button()
Me.btnEdit = New System.Windows.Forms.Button()
Me.btnSave = New System.Windows.Forms.Button()
Me.btnCancel = New System.Windows.Forms.Button()
CType(Me.SplitContainer1, System.ComponentModel.ISupportInitialize).BeginInit()
Me.SplitContainer1.Panel1.SuspendLayout()
Me.SplitContainer1.Panel2.SuspendLayout()
Me.SplitContainer1.SuspendLayout()
CType(Me.dg, System.ComponentModel.ISupportInitialize).BeginInit()
Me.SuspendLayout()

'
'txtStudent_ID
'
Me.txtStudent_ID.Location = New System.Drawing.Point(100, 25)
Me.txtStudent_ID.Name = "txtStudent_ID"
Me.txtStudent_ID.Size = New System.Drawing.Size(150, 20)
Me.txtStudent_ID.TabIndex = 1

'
'txtFirstName
'
Me.txtFirstName.Location = New System.Drawing.Point(100, 52)
Me.txtFirstName.Name = "txtFirstName"
Me.txtFirstName.Size = New System.Drawing.Size(236, 20)
Me.txtFirstName.TabIndex = 2

'
'txtLastName
'
Me.txtLastName.Location = New System.Drawing.Point(100, 79)
Me.txtLastName.Name = "txtLastName"
Me.txtLastName.Size = New System.Drawing.Size(236, 20)
Me.txtLastName.TabIndex = 3

'
'Label1
'
Me.Label1.AutoSize = True
Me.Label1.Location = New System.Drawing.Point(36, 28)
Me.Label1.Name = "Label1"
Me.Label1.Size = New System.Drawing.Size(58, 13)
Me.Label1.TabIndex = 4
Me.Label1.Text = "Student ID"

'
'Label2
'
Me.Label2.AutoSize = True
Me.Label2.Location = New System.Drawing.Point(36, 55)
Me.Label2.Name = "Label2"
Me.Label2.Size = New System.Drawing.Size(57, 13)
Me.Label2.TabIndex = 5
Me.Label2.Text = "First Name"

'
'Label3
'
Me.Label3.AutoSize = True
Me.Label3.Location = New System.Drawing.Point(35, 82)
Me.Label3.Name = "Label3"
Me.Label3.Size = New System.Drawing.Size(58, 13)
Me.Label3.TabIndex = 6
Me.Label3.Text = "Last Name"

'
'SplitContainer1
'
Me.SplitContainer1.Location = New System.Drawing.Point(13, 13)
Me.SplitContainer1.Name = "SplitContainer1"
Me.SplitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal

'
'SplitContainer1.Panel1
'
Me.SplitContainer1.Panel1.BackColor = System.Drawing.SystemColors.ActiveCaption
Me.SplitContainer1.Panel1.Controls.Add(Me.Label4)
Me.SplitContainer1.Panel1.Controls.Add(Me.txtSearch)
Me.SplitContainer1.Panel1.Controls.Add(Me.dg)
Me.SplitContainer1.Panel1.Controls.Add(Me.btnLast)
Me.SplitContainer1.Panel1.Controls.Add(Me.btnFirst)
Me.SplitContainer1.Panel1.Controls.Add(Me.btnDisplay)
Me.SplitContainer1.Panel1.Controls.Add(Me.btnPrevious)
Me.SplitContainer1.Panel1.Controls.Add(Me.btnNext)

'
'SplitContainer1.Panel2
'
Me.SplitContainer1.Panel2.BackColor = System.Drawing.SystemColors.ActiveCaption
Me.SplitContainer1.Panel2.Controls.Add(Me.Label3)
Me.SplitContainer1.Panel2.Controls.Add(Me.txtLastName)
Me.SplitContainer1.Panel2.Controls.Add(Me.Label2)
Me.SplitContainer1.Panel2.Controls.Add(Me.txtStudent_ID)
Me.SplitContainer1.Panel2.Controls.Add(Me.Label1)
Me.SplitContainer1.Panel2.Controls.Add(Me.txtFirstName)
Me.SplitContainer1.Size = New System.Drawing.Size(458, 365)
Me.SplitContainer1.SplitterDistance = 225
Me.SplitContainer1.TabIndex = 0

'
'Label4
'
Me.Label4.AutoSize = True
Me.Label4.Location = New System.Drawing.Point(15, 12)
Me.Label4.Name = "Label4"
Me.Label4.Size = New System.Drawing.Size(58, 13)
Me.Label4.TabIndex = 13
Me.Label4.Text = "Student ID"

'
'txtSearch
'
Me.txtSearch.Location = New System.Drawing.Point(78, 9)
Me.txtSearch.Name = "txtSearch"
Me.txtSearch.Size = New System.Drawing.Size(334, 20)
Me.txtSearch.TabIndex = 0

'
'dg
'
Me.dg.AllowUserToAddRows = False
Me.dg.AllowUserToDeleteRows = False
Me.dg.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize
Me.dg.Location = New System.Drawing.Point(4, 35)
Me.dg.Name = "dg"
Me.dg.ReadOnly = True
Me.dg.Size = New System.Drawing.Size(451, 149)
Me.dg.TabIndex = 1

'
'btnLast
'
Me.btnLast.Location = New System.Drawing.Point(311, 190)
Me.btnLast.Name = "btnLast"
Me.btnLast.Size = New System.Drawing.Size(60, 23)
Me.btnLast.TabIndex = 6
Me.btnLast.Text = "Last"
Me.btnLast.UseVisualStyleBackColor = True

'
'btnFirst
'
Me.btnFirst.Location = New System.Drawing.Point(113, 190)
Me.btnFirst.Name = "btnFirst"
Me.btnFirst.Size = New System.Drawing.Size(60, 23)
Me.btnFirst.TabIndex = 3
Me.btnFirst.Text = "First"
Me.btnFirst.UseVisualStyleBackColor = True

'
'btnDisplay
'
Me.btnDisplay.Location = New System.Drawing.Point(4, 190)
Me.btnDisplay.Name = "btnDisplay"
Me.btnDisplay.Size = New System.Drawing.Size(58, 23)
Me.btnDisplay.TabIndex = 2
Me.btnDisplay.Text = "Refresh"
Me.btnDisplay.UseVisualStyleBackColor = True

'
'btnPrevious
'
Me.btnPrevious.Location = New System.Drawing.Point(179, 190)
Me.btnPrevious.Name = "btnPrevious"
Me.btnPrevious.Size = New System.Drawing.Size(60, 23)
Me.btnPrevious.TabIndex = 4
Me.btnPrevious.Text = "Previous"
Me.btnPrevious.UseVisualStyleBackColor = True

'
'btnNext
'
Me.btnNext.Location = New System.Drawing.Point(245, 190)
Me.btnNext.Name = "btnNext"
Me.btnNext.Size = New System.Drawing.Size(60, 23)
Me.btnNext.TabIndex = 5
Me.btnNext.Text = "Next"
Me.btnNext.UseVisualStyleBackColor = True

'
'btnNew
'
Me.btnNew.Location = New System.Drawing.Point(17, 384)
Me.btnNew.Name = "btnNew"
Me.btnNew.Size = New System.Drawing.Size(75, 23)
Me.btnNew.TabIndex = 13
Me.btnNew.Text = "New"
Me.btnNew.UseVisualStyleBackColor = True

'
'btnDelete
'
Me.btnDelete.Location = New System.Drawing.Point(177, 384)
Me.btnDelete.Name = "btnDelete"
Me.btnDelete.Size = New System.Drawing.Size(75, 23)
Me.btnDelete.TabIndex = 15
Me.btnDelete.Text = "Delete"
Me.btnDelete.UseVisualStyleBackColor = True

'
'btnEdit
'
Me.btnEdit.Location = New System.Drawing.Point(98, 384)
Me.btnEdit.Name = "btnEdit"
Me.btnEdit.Size = New System.Drawing.Size(75, 23)
Me.btnEdit.TabIndex = 18
Me.btnEdit.Text = "Edit"
Me.btnEdit.UseVisualStyleBackColor = True

'
'btnSave
'
Me.btnSave.Location = New System.Drawing.Point(312, 384)
Me.btnSave.Name = "btnSave"
Me.btnSave.Size = New System.Drawing.Size(75, 23)
Me.btnSave.TabIndex = 15
Me.btnSave.Text = "Save"
Me.btnSave.UseVisualStyleBackColor = True

'
'btnCancel
'
Me.btnCancel.Location = New System.Drawing.Point(393, 384)
Me.btnCancel.Name = "btnCancel"
Me.btnCancel.Size = New System.Drawing.Size(75, 23)
Me.btnCancel.TabIndex = 16
Me.btnCancel.Text = "Cencel"
Me.btnCancel.UseVisualStyleBackColor = True

'
'Form1
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(487, 417)
Me.Controls.Add(Me.btnCancel)
Me.Controls.Add(Me.btnEdit)
Me.Controls.Add(Me.btnSave)
Me.Controls.Add(Me.btnDelete)
Me.Controls.Add(Me.btnNew)
Me.Controls.Add(Me.SplitContainer1)
Me.Name = "Form1"
Me.Text = "Form1"
Me.SplitContainer1.Panel1.ResumeLayout(False)
Me.SplitContainer1.Panel1.PerformLayout()
Me.SplitContainer1.Panel2.ResumeLayout(False)
Me.SplitContainer1.Panel2.PerformLayout()
CType(Me.SplitContainer1, System.ComponentModel.ISupportInitialize).EndInit()
Me.SplitContainer1.ResumeLayout(False)
CType(Me.dg, System.ComponentModel.ISupportInitialize).EndInit()
Me.ResumeLayout(False)

End Sub

Friend WithEvents txtStudent_ID As System.Windows.Forms.TextBox
Friend WithEvents txtFirstName As System.Windows.Forms.TextBox
Friend WithEvents txtLastName As System.Windows.Forms.TextBox
Friend WithEvents Label1 As System.Windows.Forms.Label
Friend WithEvents Label2 As System.Windows.Forms.Label
Friend WithEvents Label3 As System.Windows.Forms.Label
Friend WithEvents SplitContainer1 As System.Windows.Forms.SplitContainer
Friend WithEvents dg As System.Windows.Forms.DataGridView
Friend WithEvents btnDisplay As System.Windows.Forms.Button
Friend WithEvents btnFirst As System.Windows.Forms.Button
Friend WithEvents btnPrevious As System.Windows.Forms.Button
Friend WithEvents btnNext As System.Windows.Forms.Button
Friend WithEvents btnLast As System.Windows.Forms.Button
Friend WithEvents btnNew As System.Windows.Forms.Button
Friend WithEvents txtSearch As System.Windows.Forms.TextBox
Friend WithEvents btnDelete As System.Windows.Forms.Button
Friend WithEvents btnEdit As System.Windows.Forms.Button
Friend WithEvents Label4 As System.Windows.Forms.Label
Friend WithEvents btnSave As System.Windows.Forms.Button
Friend WithEvents btnCancel As System.Windows.Forms.Button

End Class



เขียนคำสั่งภายใต้ไฟล์ Form1.vb
จากนั้นให้ไปดับเบิ้ลคลิกที่ฟอร์ม Form1.vb เพื่อเขียนโค้ดคำสั่งภาษา VB
ให้นำคำสั่งด้านล่างไปแทนคำสั่ง VB เดิมได้เลย

Source Code -> Form1.vb

Imports System.Data
Imports System.Data.SqlClient

Public Class Form1

Private ds As New DataSet()
'private cs = ConfigurationSettings.AppSettings["conMyData"]
Private cs = New SqlConnection("Data Source=.\SQLEXPRESS1;Initial Catalog=MYDATA;Integrated Security=True")
Private da = New SqlDataAdapter()
Private tblStudentBS = New BindingSource() 'สำหรับผูก dataset กับ object

' For Add, Edit Record
Private lNew As Boolean
Private cKey As String

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
DisplayData()
'ผูก ds กับ object
tblStudentBS.DataSource = ds.Tables("tblStudent") 'tblStudentBS.DataSource = ds.Tables(0)
txtStudent_ID.DataBindings.Add(New Binding("Text", tblStudentBS, "Student_ID"))
txtFirstName.DataBindings.Add(New Binding("Text", tblStudentBS, "FirstName"))
txtLastName.DataBindings.Add(New Binding("Text", tblStudentBS, "LastName"))

Me.SplitContainer1.Panel2.Enabled = False

Me.btnSave.Enabled = False
Me.btnCancel.Enabled = False
End Sub

Private Sub txtSearch_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtSearch.TextChanged
DisplayData()
End Sub

Private Sub btnDisplay_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDisplay.Click
DisplayData()
End Sub

Private Sub btnFirst_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnFirst.Click
tblStudentBS.MoveFirst()
dgUpdate()
End Sub

Private Sub btnPrevious_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPrevious.Click
tblStudentBS.MovePrevious()
dgUpdate()
End Sub

Private Sub btnNext_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnNext.Click
tblStudentBS.MoveNext()
dgUpdate()
End Sub

Private Sub btnLast_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnLast.Click
tblStudentBS.MoveLast()
dgUpdate()
End Sub

Private Sub btnNew_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnNew.Click
txtStudent_ID.Text = ""
txtFirstName.Text = ""
txtLastName.Text = ""
lNew = True
onEntry()
End Sub

Private Sub btnEdit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnEdit.Click
Try
cKey = ds.Tables("tblStudent").Rows(tblStudentBS.Position)(0) 'Column 0 is key field
lNew = False
onEntry()
Catch ex As Exception
'
End Try
End Sub

Private Sub onEntry()
SplitContainer1.Panel2.Enabled = True
txtStudent_ID.Focus()
SplitContainer1.Panel1.Enabled = False
btnNew.Enabled = False
btnEdit.Enabled = False
btnDelete.Enabled = False
btnSave.Enabled = True
btnCancel.Enabled = True
End Sub

Private Sub offEntry()
SplitContainer1.Panel1.Enabled = True
txtSearch.Focus()
SplitContainer1.Panel2.Enabled = False
btnNew.Enabled = True
btnEdit.Enabled = True
btnDelete.Enabled = True
btnSave.Enabled = False
btnCancel.Enabled = False
End Sub

Private Sub btnDelete_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDelete.Click
Try
Dim dr As DialogResult
dr = MessageBox.Show("Are Your sure?" & vbLf & "There is no undo once data is deleted", "confirm Deletion", MessageBoxButtons.YesNo)
If dr = DialogResult.Yes Then
da.DeleteCommand = New SqlCommand("DELETE FROM tblStudent WHERE Student_Id = @Student_Id", cs)
da.DeleteCommand.Parameters.Add("@Student_Id", SqlDbType.VarChar).Value = ds.Tables("tblStudent").Rows(tblStudentBS.Position)(0)
cs.Open()
da.DeleteCommand.ExecuteNonQuery()
Else
MessageBox.Show("Cancel Delete")
End If
Catch ex As Exception
'
Finally
cs.Close()
DisplayData()
End Try
End Sub

Private Sub DisplayData()
da.SelectCommand = New SqlCommand("SELECT * FROM tblStudent WHERE Student_id LIKE '%" & txtSearch.Text.Trim.ToString & "%' ORDER BY Student_Id", cs)
ds.Clear()
da.Fill(ds, "tblStudent")
dg.DataSource = tblStudentBS ' dg.DataSource = ds.Tables(0)
End Sub

Private Sub dgUpdate()
dg.ClearSelection()
dg.Rows(tblStudentBS.Position).Selected = True
End Sub

Private Sub btnSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSave.Click
If lNew Then
RecordAdd()
Else
RecordEdit()
End If
offEntry()
End Sub

Private Sub btnCancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCancel.Click
DisplayData()
If lNew Then
' nothing
Else
' Set the Position property to the results of the Find method.
Dim itemFound As Integer = tblStudentBS.Find("Student_Id", cKey)
tblStudentBS.Position = itemFound
End If
offEntry()
End Sub

Private Sub RecordAdd()
Try
''-------- for show connection ---------
'cs.Open()
'MessageBox.Show(cs.State.ToString())
'cs.Close()
''-------- for show connection ---------

Dim findID As String = txtStudent_ID.Text
da.InsertCommand = New SqlCommand("INSERT INTO tblStudent VALUES(@Student_Id, @FirstName, @LastName)", cs)
da.InsertCommand.Parameters.Add("@Student_Id", SqlDbType.VarChar).Value = txtStudent_ID.Text
da.InsertCommand.Parameters.Add("@FirstName", SqlDbType.VarChar).Value = txtFirstName.Text
da.InsertCommand.Parameters.Add("@LastName", SqlDbType.VarChar).Value = txtLastName.Text
cs.Open()
da.InsertCommand.ExecuteNonQuery()

' Set the Position property to the results of the Find method.
Dim itemFound As Integer = tblStudentBS.Find("Student_Id", findID)
tblStudentBS.Position = itemFound
Catch ex As Exception
MessageBox.Show(ex.Message)
Finally
cs.Close()
DisplayData()
End Try
End Sub

Private Sub RecordEdit()
Dim x As Integer
Try
da.UpdateCommand = New SqlCommand("UPDATE tblStudent SET Student_Id = @Student_Id, FirstName = @FirstName, LastName = @LastName WHERE Student_id = @Student_id_old", cs)
da.UpdateCommand.Parameters.Add("@Student_id", SqlDbType.VarChar).Value = txtStudent_ID.Text
da.UpdateCommand.Parameters.Add("@FirstName", SqlDbType.VarChar).Value = txtFirstName.Text
da.UpdateCommand.Parameters.Add("@LastName", SqlDbType.VarChar).Value = txtLastName.Text
da.UpdateCommand.Parameters.Add("@Student_id_old", SqlDbType.VarChar).Value = cKey 'ds.Tables("tblStudent").Rows(tblStudentBS.Position)(0)
cs.Open()
x = da.UpdateCommand.ExecuteNonQuery()

'
Catch ex As Exception
MessageBox.Show(ex.Message)
Finally
cs.Close()
DisplayData()
'If (x >= 1) Then
' Set the Position property to the results of the Find method.
Dim itemFound As Integer = tblStudentBS.Find("Student_Id", cKey)
tblStudentBS.Position = itemFound
'End If

End Try
End Sub

End Class



Create Database in SQL Server : Database Name = MYDATA



Create Table : Table Name = tblStudent

USE [MYDATA]
GO

CREATE TABLE [dbo].[tblStudent](
[STUDENT_ID] [varchar](13) NOT NULL,
[FIRSTNAME] [varchar](50) NULL,
[LASTNAME] [varchar](50) NULL,
CONSTRAINT [PK_tblStudent] PRIMARY KEY CLUSTERED
(
[STUDENT_ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

สวัสดี ขอให้สนุกกับการสร้างฟอร์มป้อนข้อมูล
"I Believe in You"

Copyright(c) 2007 - 2022 by Kasem Kamolchaipisit.