วันศุกร์ที่ 2 ตุลาคม พ.ศ. 2552

Generic of

เทียบง่ายๆ ลักษณะของ คำถาม คำตอบ จะเป็น 1 to many คือ หนึงคำถามมีได้มากกว่า หนึ่งคำตอบ ถ้าเราจะเปลี่ยนจากลักษณะของการทำงานแบบ DataSet มาเป็น List แล้วจะต้องทำแบบนี้ 

public class Question
{
public string Topic {get ; set; }
public string CreatedBy { get; set;}
public List Answer {get; set;}
}

public class Answer
{
public string Detail{get; set;}
public string AnswerBy {get; set;} }

// เวลาใช้ก็แบบนี้
Question q = new Question(); 
q.Answer.Add(new Answer()); 

// การเข้าถึง List ข้างในก็

foreach foreach(Answer a in q.Answer) 
{ string jj = a.Detail; } 

[ฮิ_ฮิ]


ทำไม่ Tag T ไม่ขึ้นฟระ

วันจันทร์ที่ 21 กันยายน พ.ศ. 2552

ว้าว JQuery

ตื่นตัวช้าไปหน่อยสำหรับ libary ของตัว JQuery พอได้ไปอ่านบทความต่างๆที่ http://www.jquery.com/ ต้องบอกว่ามันน่าสนใจมากๆ เนื่องจากมี method ง่ายๆให้ใช้งานเยอะแยะ ที่สำคัญคือ cross browser และ มันเอาไปใช้กับ SharePoint ได้ดีทีเดียว ( ลองเอา fisheye ไปใช้แล้ว ok เลย ) น่าจะมาช่วย SharePoint ที่ไม่ support toolkits ของ Ajax วิธีใช้ก็ง่ายมั่กๆ ไป download file .Js ที่ http://www.jquery.com/ ( jqueryxxxx.js) จากนั้นก็ Src ธรรมดาภายใต้ tag head เสร็จแล้ว ( ^0^ ) แล้วจะเขียนอะไรก็เขียนเลย เป็นลักษณะ javascript กับ css เป็นหลัก นอกจากนี้ยังสามารถไปโหลด plugin ต่างๆ มาใช้งานได้อีกด้วย ซึ่งมันก็เหมือนๆ กับ toolkits ของ ajax น่ะแหล่ะ ยัง ยังไม่พอ Visual Studio 2008 ยังแสดง intellisense ได้อีกตะหาก โดยการ เพิ่มไฟล์ ที่ชื่อเดียวกับ jqueryxxxx.js แต่มี -doc เข้าไปใน tag head ด้วย ( วางไว้ที่เดียวกัน ) เยี่ยม !!!!

OWA + SharePoint Webpart

Moss2007 + OWA2003 มีปัญหาในกรณีเขียน WP ไป ติดต่อ Inbox , Contact , Task , bla bla แล้วอยู่หน้าเดียวกันไม่ได้ วิธีแก้ ให้ใช้ Iframe ชี้ไปที่ OWA URL แทน แล้วตามด้วย command แบบนี้ string mailcontent = "/tasks?cmd=contents&part=1"; string loginname = SPContext.Current.Web.CurrentUser.LoginName; string account = loginname.Remove(0, loginname.IndexOf("\\") + 1); string mail = account + "@owa.com"; string URL = @"http://mail.owa.com/exchange/" + mail + mailcontent; // ConfigurationManager.AppSettings["ExchangeServerUrl"]; this.frame.Attributes.Add("src", URL); หรืออีกวิธีก็คือ ไปสร้าง Aspx มาแต่ละ box แล้วใช้ wp PageViewer ชี้ไปแต่ละ page ( จริงๆ มันก็ IFrame แหล่ะนะ - -a ) อีกวิธีนึง แบบ new instance OWATasksPart wptask = new OWATasksPart(); wptask.Title = "My Task"; string workmail = SPContext.Current.Web.CurrentUser.Email; string mailcontent = "/cmd=contents&module=tasks"; wptask.MailboxName = workmail; wptask.OWAServerAddressRoot = @"http://mail.owa.com/exchange" + workmail + mailcontent; // ConfigurationManager.AppSettings["ExchangeServerUrl"]; wptask.Height = "500"; wptask.Width = "400"; Controls.Add(wptask); base.CreateChildControls(); คิดว่าถ้าเป็น owa 2007 น่าจะ smooth ( มั้ง ) ไม่มีให้ลองซะงั้น -"-

วันพฤหัสบดีที่ 24 กรกฎาคม พ.ศ. 2551

การสร้าง Site ผ่าน WebService ของ Sharepoint

[SoapDocumentMethodAttribute("http://schemas.microsoft.com/sharepoint/soap/CreateSite", RequestNamespace="http://schemas.microsoft.com/sharepoint/soap/", ResponseNamespace="http://schemas.microsoft.com/sharepoint/soap/", Use=SoapBindingUse.Literal, ParameterStyle=SoapParameterStyle.Wrapped)] public string CreateSite ( string Url, string Title, string Description, int Lcid, string WebTemplate, string OwnerLogin, string OwnerName, string OwnerEmail, string PortalUrl, string PortalName ) Value Site Definition STS#0 Team Site STS#1 Blank Site STS#2 Document Workspace MPS#0 Basic Meeting Workspace MPS#1 Blank Meeting Workspace MPS#2 Decision Meeting Workspace MPS#3 Social Meeting Workspace MPS#4 Multipage Meeting Workspace BLOG#0 Blog Site WIKI#0 Wiki Site Example Web_Reference_Folder_Name.Admin admService = new Web_Reference_Folder_Name.Admin(); admService.Credentials= System.Net.CredentialCache.DefaultCredentials; try { admService.CreateSite("http://Server_Name/sites/SiteCollection_Name", "Title", "Description", 1033, "STS#0", "Domain_Name\\User_Alias","User_Display_Name", "User_E-mail","",""); } catch (System.Web.Services.Protocols.SoapException ex) { MessageBox.Show("Message:\n" + ex.Message + "\nDetail:\n" + ex.Detail.InnerText + "\nStackTrace:\n" + ex.StackTrace); } Ref : http://msdn.microsoft.com/en-us/library/administration.admin.createsite.aspx

TemplateID On Sharepoint 2007

ID - FOLDER (extra info) - Configurations

0 - GLOBAL (SetupPath=global) - "Global template" 1 - STS - "windows SharePoint Services Site", "Team Site", "Blank Site", "Document Workspace" 2 - MPS - "Basic Meeting Workspace", "Blank Meeting Workspace", "Decision Meeting Workspace", "Social Meeting Workspace", "Multipage Meeting Workspace" 3 - CENTRALADMIN - "Central Admin Site" 4 - WIKI - "Wiki Site" 7 - BDR - "Document Center" 9 - BLOG - "Blog" 20 - SPS (OBSOLETE) - "SharePoint Portal Server Site" 21 - SPSPERS - "SharePoint Portal Server Personal Space" 22 - SPSMSITE - "Personalization Site" 30 - SPSTOC (OBSOLETE) - "Contents area Template" 31 - SPSTOPIC (OBSOLETE) - "Topic area template" 32 - SPSNEWS (OBSOLETE) - "News area template" 33 - SPSNHOME (SubWebOnly) - "News Home template" 34 - SPSSITES - "Site Directory area template" 36 - SPSCOMMU (OBSOLETE) - "Community area template" 38 - SPSREPORTCENTER - "Report Center Site" 39 - CMSPUBLISHING (SetupPath=SiteTemplates\PUBLISHING) - "Publishing and Team Collaboration Site" 40 - OSRV (SetupPath=SiteTemplates\OSRV) - "Shared Services Administration Site" 47 - SPSPORTAL - "Corporate Intranet Site" 50 - SRCHCEN - "Search Center" 51 - PROFILES - "Profiles" 52 - BLANKINTERNETCONTAINER - "Internet Presence Web Site" 53 - BLANKINTERNET - "Publishing Site", "Press Releases Site", "Publishing Site" 54 - SPSMSITEHOST - "My Site Host" 90 - SRCHCENTERLITE (SetupPath=SiteTemplates\SRCHCENTERLITE) - "Search Center Lite" 6221 - PWA (SetupPath=SiteTemplates\PWA) - "Project Web Access Site" 6215 - PWS (SetupPath=SiteTemplates\PWS) - "Project Workspace" 14483 - OFFILE - "Records Repository", "Records Repository"

Ref : http://blogs.msdn.com/dwinter/archive/2006/07/07/659613.aspx

วันจันทร์ที่ 24 มีนาคม พ.ศ. 2551

Install Reporting Services 2005

1. Get Started Install Microsoft SQL Server 2005 ( I tested on Ms SQL Server 2005 Standard Edition ) .
2. Click menu install Server Components, tools.
3. Choose All Components to install , Business Intelligence Development Studio will be store in Client Components.

After installed finish you will see as below :









You will see "SQL Server Business Intelligence Development Studio" in you program list and your IIS will be created 2 Virtual Directory ::

1. Reports - I will find more information and told you later about this site.
2. ReportServer - For deploy your report and allow user view report via browser.

Also MS SQL Server will created 2 Table as Below ::

1. Report Server
2. Report ServerTempDB
For the next day, I will introduce simple report On "SQL Server Business Intelligence Development Studio"

God bless you.

วันพุธที่ 16 มกราคม พ.ศ. 2551

Why JavaScript Topic can't be displayed ?

l@#$%^&* :-( I have to tranfer some topic from space.live but i have some problem about JavaScript Topic. It doen't show in Blogger. - -" May be i must change that's topic to the picture. uhh

วันอังคารที่ 15 มกราคม พ.ศ. 2551

Sequence Css Block with A tag

You should coding A tag sequence in Css as below. A:link A:visited A:hover A:active
If you place A:hover before A:link or A:visited. The property in A:hover  will not be display.

วันอาทิตย์ที่ 13 มกราคม พ.ศ. 2551

BackGround Worker - Progress Bar

การใช้ Background Worker ก็ลากมาแปะในฟอร์ม แล้วดูว่า เราต้องการทำอะไรบ้างดูใน Property & Event
workerReport Progress = True << รายงานการเปลี่ยนแปลง ใช้คู่กับ Event Progress changed ( มั้งนะ เดาเอา )
workerSupport Cancellation =True << กด Cancel ขณะ Runtime
Event
DoWork ต้องใช้ฟตลอด
RunworkerCompleted ให้ทำอะไรหลังที่ Bgw ทำงานเสร็จ

Private Sub btnGentoDb_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnGentoDb.Click

Me.bgw.RunWorkerAsync(.dgv.Rows.Count - 1) '---- ส่งจำนวนรอบ หรือไม่ส่งก็ว่างไว้

End Sub

Private Sub bgw_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bgw.DoWork

Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)

'เรียก แบบ Function ให้เอา ผลลัพธ์ ใส่ให้ e.result ด้วย

' e.Result = Function(parameter)

'เรียกแบบ Sub

Me.AppendData(e.Argument, worker, e) <<<<<< ไปเรียก Method ที่ทำการประมวลผลเช่นดึงค่ามาจาก Db

End Sub

Private Sub bgw_ProgressChanged(ByVal sender As System.Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles bgw.ProgressChanged

'ทำงานหลัง จากมีการเรียก wk.ReportProgress(Pvalue)

'แสดงผล ความก้าวหน้าการทำงาน

pgb.Value = e.ProgressPercentage

End Sub

Private Sub bgw_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bgw.RunWorkerCompleted

If Not (e.Error Is Nothing) Then

'ทำงานเมื่อเกิด exception ทำให้ การทำงานหยุด

MessageBox.Show(e.Error.Message.ToString, " Error ", MessageBoxButtons.OK, MessageBoxIcon.Error)

ElseIf e.Cancelled Then

' ทำงานหลัง เรียก CancelAsync.

MessageBox.Show(" Cancelled")

Else

'กรณี ปกติ ทำงานเสร็จหมดแล้ว มาจบที่ตรงนี้

'ให้กำหนดว่า(เมื่อทำงานเสร็จแล้วให้ทำอะไร)

' Finally, handle the case where the operation succeeded.

'ก็แค่บอกว่า ทำเสร็จ

Me.btnGentoDb.Enabled = True

End If

End Sub

Special Thanks ..

Gf Board Gf Minilab V.1

อืมม ทบทวนความจำเรื่อง Dispose กับ Obj

ถามเรื่องตัวแปรทั่ว ๆ ที่ใช้ใน sub พอใช้เสร็จต้องจัดการอะไรกับตัวแปรนั้นๆ ไหมครับ

ถาม VB.NET และ C#.NET
ตัวแปรทั่ว ๆ ไปที่เราประกาศขึ้นมาใช้ในแต่ละ sub พอใช้ sub นั้นเสร็จแล้วต้องจัดการอะไรกับตัวแปรต่อไหมครับ
อย่างเช่นตัวแปร integer,string,double,sqldatareader,datatable,sqlcommand,sqlconnection อื่น ๆ อีกมากมาย
ปกติแล้วถ้าเราไม่ได้ทำอะไรกับตัวแปรเหล่านี้ ตัวภาษาเองจะสามารถจัดการให้เราอัตโนมัติได้ไหมครับ(ทำลายตัวแปรนั้นไหม) เพราะส่วนใหญ่ตัวแปรอย่างพวก string,integer อะไรพวกนี้เหมือนส่วนใหญ่ไม่ได้ให้ความสำคัญกัน แต่จะให้ความสำคัญกับพวก Datatable,Dataset,Connection อะไรประมาณนี้ครับ ขอคำแนะนำด้วยครับ
ยอดชาย
----------------------------------------
1. ตัวแปรที่เป็น value type เช่น Structure, Integer, Byte, Boolean ฯลฯ
ไม่ต้องทำอะไรทั้งสิ้น เพราะมันจะถูกคืนหน่วยความจำเองเมื่อโค้ดออกจาก scope ที่ประกาศตัวแปรนั้นๆ
เช่น ตัวแปร x As Integer ใน Sub A()
เมื่อ Sub A เริ่มทำงาน เมื่อไหร่ ตัวแปร x จึง "เกิด" กินพื้นที่ 4 ไบต์ใน stack
และเมื่อเจอ End Sub (หรือเมื่อการทำงานออกจาก Sub A) ตัวแปร x ก็จะ "ตาย" และคืนหน่วยความจำ
2. ตัวแปรที่เป็น Reference type เช่น Class, String, Array, Delegate
โดยตัวแปรมันเอง (เรียกว่า object reference) นี่ส่วนหนึ่ง
และเมื่อมีการสร้างอ๊อบเจ็กต์ (object) แล้วเอาตัวแปรเมื่อกี้ไปชี้ นี่ก็อีกส่วนหนึ่ง
Sub Foo()
Dim c As Course ' ---- c เป็น object reference
c = New Course() ' ---- เกิดการสร้าง object ใหม่เกิดขึ้นมา แล้วให้ c ไปชี้
c = Nothing ' ---- ไม่จำเป็น
End Sub
เฉพาะส่วน object reference จะใช้พื้นที่ 4 ไบต์ใน เครื่อง 32-bit
หรือ 8 ไบต์ในเครื่อง 64-bit ก็อยู่ใน stack จะเกิดและตายในทำนองเดียวกับ Value types ทั้งหลาย
ดังนั้น เราจะกำหนดค่าให้ Nothing หรือไม่ ก็ไม่จำเป็นนัก คือมีค่าผลเหมือนๆ กัน
ส่วนที่เป็นเรื่องหน่อย ก็ตรงอ๊อบเจ็กต์ที่สร้างขึ้น (ในหน่วยความจำของโปรแกรม
ส่วนที่เรียกว่า managed heap นั่นแหล่ะครับ)
ตรงนี้ถูกจัดการด้วย Garbage Collector (GC)
ตอบย่อๆ เฉพาะสำหรับกระทู้นี้คือ
ถ้า อ๊อบเจ็กต์นั้นมีเมธอด Dispose หรือ Implements อินเทอร์เฟส IDisposable
ก็ให้เรียกเมธอด Dispose นั้นด้วย
ก่อนที่ตัวแปร reference นั้นจะถูกกำหนดเป็น Nothing หรือ "ตาย" ไปเสียก่อน
เช่น
Sub Foo2()
Dim c As New Course()
...
If (TypeOf c Is IDisposable) Then
DirectCast(c, IDisposable).Dispose()
End If
c = Nothing ' ---- ไม่จำเป็นอยู่ดี
End Sub
ไม่อย่างนั้นแล้ว เดี๋ยว c มันเกิด nothing หรือ ตายไป
เราจะไม่มีโอกาสเปลี่ยนใจมาเรียก Dispose ให้กับ "อ๊อบเจ็กต์" อีกแล้ว
ปล.
เรื่องของ Dispose ให้ค้นหาอ่านได้จากเว็บบอร์ดเกรทเฟรนส์ เพิ่มเติมด้วยจะดีมาก
นอกจากกรณีที่ควร Dispose ถ้ามีให้ Dispose แล้ว
อีกกรณีก็เรื่อง COM object ที่ คุณนายเคยเขียนวิธีการ Release COM object อย่างถูกวิธีไว้
ก็ค้นหาจากเว็บบอร์ดนี้ได้อีกเช่นกัน.
surrealist
----------------------------------------
ขอบคุณมากนะครับที่อุตส่าห์สละเวลามาอธิบายแบบละเอียดเลย
จากที่ผมเข้าใจ คือ
1.class ที่เราสร้างขึ้นมาเองเวลาที่ใช้น่าจะเป็นแบบนี้ใช่ไหมครับ (ตัวอย่างที่อาจารย์ให้ดู)
Sub Foo2()
Dim c As New Course()
...
If (TypeOf c Is IDisposable) Then
DirectCast(c, IDisposable).Dispose()
End If
c = Nothing ' ---- ไม่จำเป็นอยู่ดี
End Sub
2.ส่วนที่ว่า
c = Nothing ' ---- ไม่จำเป็นอยู่ดี หมายถึงไม่มีประโยชน์ที่ใช้คำสั่ง c = Nothing หากทำ Dispose แล้ว
(ความเข้าใจของผมในตอนนี้คือ C คือ Object ที่ Instant มาจาก Class Course ถูกไหมครับ)
3.ตัวแปรพวกนี้ sqldatareader,datatable,sqlcommand,sqlconnection (Reference Type )
ตอนที่จบ sub ถ้าอ๊อบเจ็กต์นั้นมีเมธอด Dispose หรือ Implements อินเทอร์เฟส IDisposable ก็ให้เรียกเมธอด Dispose นั้นด้วย
ขอบคุณมากครับ
ปล.ผมเพิ่งทราบนะครับว่า string เป็นตัวแปรแบบ Reference type แล้วตัวแปรแบบ string ต้องจัดการยังไงเมื่อจบ sub ครับ **
ยอดชาย
----------------------------------------

ตอบ

1. ใช่ครับ แต่เรามีประโยคที่สั้นกว่าในการ dispose คือ Using statement เช่น
Using x As New Class1
' ---- use the x object.
End Using ' --- at End Using, x will be disposed if it implements IDisposable.
2. ต้องเข้าใจให้ชัดเจนก่อนว่า c ไม่ใช่อ๊อบเจ็กต์ แต่เป็น object reference (ตัวpointerชี้ไปยัง object เท่านั้น)
การที่ให้ c เป็น Nothing คือ ตัวชี้ที่เคยชี้ไปยังอ๊อบเจ็กต์ ก็ไม่ชี้แล้ว ส่วนอ๊อบเจ็กต์นั้นยังคงอยู่ครับ

"ไม่มีประโยชน์ที่ใช้คำสั่ง c = Nothing หากทำ Dispose แล้ว"
ไม่ถูกต้องทั้งหมดครับ แต่ก็ไม่ผิด
3. สังเกตง่ายๆ ว่า ถ้า class นั้นๆ มีเมธอด Close ให้เรียก Close เมื่อใช้เสร็จ
ถ้ามีเมธอด Dispose ให้เรียก Dispose เมื่อใช้เสร็จ (หรือใช้ Using statement แทน)
ความแตกต่างระหว่าง Close กับ Dispose ก็มีครับ
แต่ก่อนผมเคยบอกในเว็บบอร์ดว่ามันไม่ต่างกัน ตอนนี้ขอเปลี่ยนข้อมูลใหม่นะครับ
Close - ใช้เรียกเมื่อเราเลิกใช้แล้ว แต่อ๊อบเจ็กต์นั้นยังใช้ซ้ำได้อีก
Dispose - ใช้เรียกเมื่อเราเลิกใช้แล้วจริงๆ อ๊อบเจ็กต์นั้นจะอยู่ในสถานะที่ใช้อีกไม่ได้
ตัวแปร reference นอกเหนือจาก Class เช่น String, Array, Delegate จะอยู่ในการควบคุม
ของ CLR ครับ เราไม่จำเป็นต้องไปจัดการด้วยตนเองเลย จริงๆ แล้ว อาจจะเป็นหน้าที่ของ
คอมไพเลอร์ของภาษาที่เราใช้ เพราะโดย syntax มันก็พยายามทำให้เรามองไม่เห็นอยู่แล้ว
ว่าเป็น reference type เช่น เราไม่จำเป็นต้อง new อ๊อบเจ็กต์ string เอง
surrealist
----------------------------------------
ขอบคุณ อาจารย์ , คุณ ยอดชาย , GF Board ครับ

การใช้ Using .. End Using

MESSAGE #18854 (อ่าน 158 ครั้ง) Using .... End Using ใช้ยังไงครับ Using .... End Using ใช้ยังไงครับ กับ Try ... Catch ... End Try

ใช้ต่างกันยังไงครับ

ขอขคุณครับ ปอ

-----------------------

Using จะทำการ Dispose ตัวแปร command ให้อัตโนมัติครับ

ส่วน Try .. Catch ใช้ดักเมื่อเกิด throw exception

tony

----------------------

Using sample

Using conn As New SqlConnection(dsn) Using cmd As New SqlCommand("SELECT * FROM Employees", conn) conn.Open() Using rdr As SqlDataReader = cmd.ExecuteReader() While rdr.Read() Console.WriteLine(rdr(0)) End While End Using End Using End Using Nine (นาย) -------------------- ต้วอย่าง แบบไม่ใช้ Using Dim x2 As New Employee("x2") x2.Name = "test"

If (TypeOf x2 Is IDisposable) Then DirectCast(x2, IDisposable).Dispose() End If แบบใช้ Using Using x3 As New Employee("x3") x3.Name = "test" End Using

Iwis -------------------------------

Using cn1 As New SqlConnection(My.Settings.NorthwindConnectionString), _ cmd1 As New SqlCommand(sql1, cn1) cn1.Open() Dim reader As DataReader = cmd1.ExecuteReader() Do While (reader.Read()) Dim sql2 As String sql2 = "...." Using cn2 As New SqlConnection(My.Settings.NorthwindConnectionString), _ cmd2 As New SqlCommand(sql2, cn2) cn2.Open() cmd2.ExecuteNonQuery() End Using Loop reader.Close End Using surrealist ---------------------- Using da As New SqlDataAdapter(sql, cn) Dim cmd As SqlCommand = da.SelectCommand cmd.Parameters.Add("@para1", SqlDbType.XYZ).Value = yourValue ' ---- เมื่อเราสั่ง Fill, DataAdapter จะเอา SelectCommand ของมันไป ExecuteReader ' ---- เพื่อนำข้อมูลที่ได้จาก DataReader มา "Fill" ใส่ DataSet/DataTable ที่เรากำหนด da.Fill(ds, "Table1") End Using ' ... Return(ds)

surrealist

ขอบคุณทุกๆท่านที่มีรายชื่อครับ ที่มา ณ www.greatfriends.biz

การใช้ Parameter คู่กับ Dataset จะเขียนยังไงดีครับ

การใช้ Parameter คู่กับ Dataset จะเขียนยังไงดีครับ

คือ ปรกติผมใช้ parameter กับ พวก .ExecuteNonquery หรือไม่ก็ .ExecuteReader น่ะครับ แต่ทีนี้ว่ามีปัญหาคือ
Function ในการ Query ข้อมูลนั้น เป็นการ return ค่าออกมาเป็น Dataset ซึ่งผมไม่รู้ว่าจะวาง parameter ยังไงให้ ตรง query Dataset รู้จักค่า Parameter ด้วย
ยกตัวอย่างการเขียนนะครับ
Dim dr As SqlDataReader

Try

checkOpen() << เกี่ยวกับเปิดปิดการ Connect

Dim sql As String = " select * From MyTable Where id = @id And Name Like @Name "

Dim cmd As New SqlCommand(sql, cn)

cmd.Parameters.Add("@id", SqlDbType.DateTime).Value = sdate

cmd.Parameters.Add("@Name", SqlDbType.DateTime).Value = edate

dr = cmd.ExecuteReader

dr.Read()

If dr.HasRows = True Then

cmd.Dispose()

dr.Close()

Dim da As New SqlDataAdapter(sql, cn)

Dim ds As New DataSet

da.Fill(ds, "Test")

da.Dispose()

Return ds <<< คืนค่าออกไป

Else

cmd.Dispose()

dr.Close()

End If

Catch ex As Exception

MsgBox(ex.Message & " จาก Function Test, TestClass")

Finally

cn.Dispose()

End Try

คือ ถ้าเขียนแบบนี้ ตัว SqlDataAdapter มันจะไม่รู้จัก ตัว Parameter น่ะครับ

ไม่ทราบว่ามันสามารถเขียนได้หรือไม่ครับ

ขอบคุณมากครับ
MrSuthin วันที่ส่ง: 3 ม.ค. 50 18:43 GMT+7 วันที่ปรับล่าสุด: 3 ม.ค. 50 19:50 GMT+7
REPLY #1 (32444)
คุณ MrSuthin ยังใช้วิธีการเขียนแบบ Visual Studio 2003 (.NET 1.1) อยู่นะครับ
ยังไม่ใช้ .NET 2 หรือครับ
ใน DataAdapter จะมีอ๊อบเจ็กต์ Command ของมันเองอยู่สี่ตัว
กรณีนี้เรากำลังจะสนใจเฉพาะ SelectCommand ผมแนะนำโค้ดให้นิดหน่อย
คุณสุทินก็คงเขียนต่อเองได้แล้วมั้งครับ
Dim sql As String = "SELECT ... WHERE col1 = @para1;"
Dim ds As New DataSet
' ...
Using da As New SqlDataAdapter(sql, cn)
Dim cmd As SqlCommand = da.SelectCommand
cmd.Parameters.Add("@para1", SqlDbType.XYZ).Value = yourValue
' ---- เมื่อเราสั่ง Fill, DataAdapter จะเอา SelectCommand ของมันไป ExecuteReader
' ---- เพื่อนำข้อมูลที่ได้จาก DataReader มา "Fill" ใส่ DataSet/DataTable ที่เรากำหนด
da.Fill(ds, "Table1")
End Using
' ...
Return(ds)

surrealist

ขอขอบคุณ อาจารย์ครับ

Datarelation กับ Dataset Read Xml

DataRelation เอา 2 Dataset มา Relation กัน โดย มันจะต้องอยู่ใน dataset ตัวเดียวกัน
'--- อันนี้เป็นการทำ Relation กับตัวมันเอง 1 Talbe ( ทำมาไมวะตู - -" )

Dim cnString As String = "Bla Bla Bla ::: OpenConnection Database"

Dim cn As New SqlConnection

With cn

If .State = ConnectionState.Open Then .Close()

cn.ConnectionString = cnString

.Open()

End With

Dim sql As String = " select top 500 "

sql &= " Ta.idTableAccount , Ta.InvNo , Ta.Amount ,"

sql &= " Ta.Volume,"

'---- Consignee "

sql &= " Cn.TitleConsignee "

sql &= " From TableAccount Ta "

sql &= " Inner Join Consignee Cn On Ta.Consignee = Cn.idConsignee "

Dim da As New SqlDataAdapter(Sql, cn)

Dim ds As New DataSet

da.Fill(ds, "ShowAllTableAccount")

Dim sqlSub As String = " select top 500 "

sqlSub &= " Tat.idTableAccount , "

sqlSub &= " Tat.Sendto , Tat.SendInv , Tat.Voy , "

sqlSub &= " Tat.etd, Tat.kaset , Tat.eu , "

sqlSub &= " Tat.isCancel,"

'---- Consignee & Country

sqlSub &= " Vs.NameVessel , de.country "

sqlSub &= " From TableAccount Tat "

sqlSub &= " inner join TableAccount TaSub On Tat.idTableAccount = TaSub.idTableAccount "

sqlSub &= " Inner Join Destination De On Tat.Country = De.idDestination "

sqlSub &= " Left Join Vessel Vs On Tat.Vessel = Vs.idVessel"

' da.SelectCommand.CommandText = sqlSub

Dim da1 As New SqlDataAdapter(sqlSub, cn)

' Dim ds1 As New DataSet

da1.Fill(ds, "ShowAllTableAccountSub")

Dim dcMaster, dcDetails As DataColumn

'--- อ่าน Field idTableAccountเก็บไว้ใน dcMaster

dcMaster = ds.Tables("ShowAllTableAccount").Columns("idTableAccount")

'--- อ่าน Field idTableAccountเก็บไว้ใน dcDetails

dcDetails = ds.Tables("ShowAllTableAccountSub").Columns("idTableAccount")

'--- สร้างความสัมพันธ์ และใส่ค่าไว้ที่ dl

Dim dl As New DataRelation("Details", dcMaster, dcDetails)

ds.Relations.Add(dl)

Dim dvm As New DataViewManager

dvm.DataSet = ds

Dim dvs As DataViewSetting

dvs = dvm.DataViewSettings("ShowAllTableAccount")

dvs.Sort = "idTableAccount"

dvs = dvm.DataViewSettings("ShowAllTableAccountSub")

dvs.Sort = "Consignee"

With FvAccount.dgvAcc

.ReadOnly = True

.DataSource = dvm

.DataMember = "ShowAllTableAccount"

End With

With FvAccount.subDgvAcc

.ReadOnly = True

.DataSource = dvm

.DataMember = "ShowAllTableAccount.idTableAccount"

End With

จะสังเกตุได้ว่า เรา Dim New DataAdpter และ Dataset แค่ครั้งแรกครั้งเดียว ส่วนครั้งที่สองนั้น เราสามารถใช้

DataAdapter ตัวเดิมได้ แล้ว จะต้องใช้ Dataset ตัวเดิม ห้าม Dim New เพราะใช้แล้ว Error ว่ามันไม่สามารถทำ

Relation กับตัว Dataset ที่ต่างกันได้ ( แปลมาว่างี้ )

ต่อมา มาเรื่องของ Ds.ReadXml เวลา Export File จากไหนๆก็ตาม ยกตัวอย่างจาก Access

Export File ออกมาแบบธรรมดาไม่ต้องเอา Schema ( จะมี Option ขั้นสูงฝัง Schema มากับ Data เลย )

เพราะถ้าฝังมาด้วย มันจะทำให้ ds.ReadXml อ่านไม่ได้

พออ่านได้เราก็เอา ds.ReadXml("d:/Test.xml") << หรือรับค่ามาจาก OpenFileDialogbox ก็ได้

แล้วก็ไป Binding ใส่ Control ต่างๆได้ ต่อ ไป การอ้างถึงก็คือ

Ds.Tables("ชื่อTable")

ข้อควรจำในการ Export File มาเป็น Dataset

**** ถ้ามี Column ตรงกับชื่อ Table มันจะทำให้การอ่านค่าผิดพลาด จะต้องไม่ให้ ชื่อ Column ไม่ซ้ำกับชื่อของ Table เด็ดขาด !!

Property Dock กับ Bring To Front ของ DataGridView

จะว่าก็ว่า ขอบ่นตัวเองหน่อย -*-
นั่งทำ app เล่นๆตัวนึง ที่มันไม่ยาก กลับทำให้เป็นเรื่องยาก เนื่องจาก เอา Panel มาลง แล้วไปตั้งเป็น Dock Top
แล้วก็ลาก DataGridView มาตั้งเป็น Dock Fill ซึ่งตอนอาจารย์สุเทพ สอน ก็บอกว่าให้ Brint To Front
เพราะว่าไม่งั้นเนี่ยะ ตัวที่ลงไปก่อน มันจะลอยทับอยู่บน Layer ที่ลากไปทีหลัง ไอเราก้ลืม
พอถึงเวลาดึงข้อมูลไป Binding กับ ตัว DataGridView ปรากฏว่าข้อมูลไม่ปรากฏ ( มี อยู่ 2 Record ทำขึ้นมาเทสต์)
ปรกติถ้ามันไม่มีข้อมูลมันก็จะขึ้น Header Text ของ Column ขึ้นมา แต่นี่ไม่ขึ้นเลย โชว์แต่พื้นของ DGV ว่างๆเทาๆ
หากันเข้าไป 3 ชม นั่งไล่ตั้งแต่ Query ไปเทียบโค้ดของเก่ามา
พึ่งมาดูหน้า Design ทีหลัง เอ๊ะใจลองคลิ๊กๆ ที่พวก Control ก็ถึงบางอ้อ
Panel มันลอยทับอยู่บน Layer ของ DataGridView นี่หว่า ก็จัดการกับ DataGridview
ให้ Bring To Front ก็จบละ -*-

การเข้าถึง Object ระหว่างคลาสภาค 2

Form1 , ClassManageForm1 , Form2
เมื่อฟอร์ม 1 ให้ ClassManageForm1 เป็นตัวจัดการ Query ข้อมูล dataset มาสักอย่าง
หลักแห่งการจำ
1. คลาสที่จะขอเข้าไปใช้งานคอนโทรลนั้นต้อง
'--- ClassManageForm1
Public F1 as Form1
Public Sub LoadData()
....
..
.
End Sub
2. คลาสที่คอนโทรลโดนใช้งานต้อง
'--- Form 1
Public C as new ClassManageForm1
Public Sub New ()
C.F1 = Me
End Sub
เท่านี้ ClassManageForm1 ก็สามารถ Assign ค่าโดยตรงให้กับฟอร์มได้ ที่นี้มาดูส่วนเพิ่ม
ถ้าเกิดว่าฟอร์ม 2 จะเข้ามาใช้งาน Sub LoadData นั้น มันจะต้องเข้าผ่านทาง Form1
( วิธีอื่นทำแล้วไม่ผ่าน ใครรู้ช่วยบอกทีครับ )
ถ้าเรา ไป Dim C as new ClassManageForm1
แล้วใช้ C.LoadData ผ่านทางฟอร์ม 2 เพื่อที่ให้ ฟอร์ม 1 Refresh ข้อมูลแล้หล่ะก็
มันจะ Error ว่าเราไม่ New ก่อนใช้ ถ้าเราไป New ก่อนใช้ มันก็จะเป็นอีก Object นึงละ
มันจะไมใช่ Obj เดิม
อธิบายมาซะยาว ( ทบทวนความเข้าใจตัวเอง - -a ) วิธีการนั้นคือ
ตอนที่เราเปิดฟอร์ม 2 ขึ้นมาให้ส่ง Me เข้าไป
'--- Form 1 อนุญาต ให้ฟอร์ม 2 เข้ามาใช้ ก็ใช้หลักการ 3 ข้อข้างบน
'------ ฟอร์มที่ถูกอ้างอิงต้อง New แล้วส่ง Me
Public C as new ClassManageForm1 <<< ต้องเป็น Public เท่าน้นเพื้อให้ F2 เห็น
Public ( Private ก็ได้นะ ) F2 as Form2
Public Sub New ()
C.F1 = Me
End Sub
Private Sub OpenForm2() '-- ป้องกันการเปิดหน้าต่างซ้ำ
Dim f as form
Dim Main as Form MainPage << ผมทำเป็น Mdi MainPage คือ ฟอร์มแม่
For each f in Main.MdiChildren
If (TypeOf F is Form2) then
f.activate
exit sub
End if
Next
F2 = New Form2
F2.RefF1 = Me
F2.MdiParent = Main
F2.Show
'--------------------------------- อันนี้เรียบร้อย สำหรับฟอร์ม 1
'--- Form 2 ก็เข้าหลักการว่า ให้อ้างถึงฟอร์ม 1 และเป็น PUblic เท่านั้น
Public RefF1 as Form1
Private Sub AddData()
...
..
.
RefF1.C.LoadData() <<<<< เวลาเรียกใช้ให้ทำแบบนี้
ให้เข้าผ่าน Form1 แล้วค่อยเข้าไปใน ClassManageForm1 โดยผ่าน .
จบข่าว

Note กันลืม

1. การเชื่อมฟิลด์ ใช้เครื่องหมาย +''+ ฟิลด์ที่ต้องการเชื่อมแล้วตามด้วย as Alias
- select name+''+Lastname As YourName , tel from [User]
2. การทำ Splash Screen แบบ Transparent บนพื้นวินโดวส์ ควรทำบน Panel เพราะถ้าทำบนฟอร์มเลย bg จะไม่หาย
แม้จะเซ็ต TransparentKey แล้วก็ตาม
3. การเข้าถึง Object ซึ่งแม้ว่าจะมีบางฟอร์มส่ง ค่า me มาให้มันแล้วก็ตามหากเรา Dim New จากฟอร์มอื่น
และใน function ที่เราต้องการใช้มีการอ้างถึงฟอร์มอื่นด้วย ต้องส่งชื่อฟอร์มอื่นให้มันด้วย เพราะว่ามันเป็ฯคนละ obj กัน
4. ในการแสดงผลของ Icon หากเป็น Mdi ฟอร์ม จะมีปัญหาคือเปิดครั้งแรก ภาพ Icon จะแสดงรูปไม่ถูกต้อง
ต้องไปใส่ ตอน Run Time ของ Event Load โดย Add ภาพเข้าไปใน Resource ก่อน
'--- Form Load
Me.Icon = My.Resource.IconName
5. กด ปุ่ม enter แล้วเลื่อน focus ไปที่ control ในฟอร์มแทนปุ่ม tab โดยการเซ็ต Form ให้ KeyPreview = True ก่อนแล้ว
ไปทำ Event KeyDown
If e.KeyCode = Keys.Enter Then SendKeys.Send("{TAB}") End If
กับ อีกวิธีนึง โดยใช้ Form.GetNextControl ใช้กับ KeyCode เหมือนเดิม
If (e.KeyCode = Keys.Enter) Then Dim ctl As Control Do ctl = Me.GetNextControl(Me.ActiveControl, forward:=True) Loop Until (ctl.CanFocus) ctl.Focus() e.Handled = True '---- ไม่มีการส่งค่า e ไปที่ไหนอีก เพื่อจบการทำงาน End If 6. การจับ Event KeyPress
if (IsNumeric(e.KeyChar)) OrElse (e.KeyChar = Chr(8)) Then Else e.Handled = True
End If
End Sub
ขอบคุณ
อาจารย์ สุเทพ http://www.greatfriends.biz

การอ้างถึง ชื่อ dataset จะผิดพลาดไม่ได้แม้แต่ช่องว่าง

สงสัยจริงๆว่า ทำไมเรา Search หาข้อมูลไม่เจอ ทำไม Datagrid View ไม่เอาข้อมูลใน Dataset มาโชว์
ไล่ไปไล่มาจนถึงบางอ้อ ในส่วนของ Dal นั้น ผมอ้างเป็น
Dim da as new SqlDataAdpter
Dim ds As new Dataset
da.Fill(ds, " SearchData ") <--- สังเกตุได้ว่า มีเว้นวรรคหน้าหลังในเครื่องหมาย Double Quote
Return ds
แต่พอเวลาไปเรียกใช้
Dim dsSearch as Dataset
Me.dgvShow.datasource = ds.Tables("SearchData") <--- ไม่มีวรรค
เวลากด Search ปั๊ป หายยกแผง เห่อะๆ
ทีหลังอ้างชื่อให้เหมือนทุกตัวและตำแหน่งดีที่สุด

การเข้าถึง Control ของอีก คลาสนึง

กตัวอย่างฟอร์มแม่กับฟอร์มลูกละกัน อย่างฟอร์มแม่ มี Status Bar เพื่อแจ้ง UserAccount ด้านล่าง
หลังจากที่ User LogIn ( หน้าฟอร์มลูก ) เสร็จ ก็จะเอา UserName เนี่ยะ ไปใส่ไว้ใน Status Bar
ทีนี้การเข้าถึง Control ของฟอร์มแม่ก็ทำได้ดังนี้ คือเราต้อง ใช้ตัวแปร Ref
'---Fomแม่ ชื่อว่า MainForm
Dim LoginPage as New Login
LoginPage.Form1 = me '<--- ส่ง Me เข้าไปให้ตัวแปรที่ Ref ถึง form แม่
LoginPage.ShowDialog()
'---Form Login ชื่อว่า Login
Public Form1 as MainForm '<--- Ref ไปถึง ฟอร์แม่
private sub btnok_click....
dim dal as new DalUser '<--- ประกาศ Object ของฐานข้อมูล
Dim HasAccount as boolean
HasAccount = Dal.CheckLogin(me.txtusername.text, me.txtpassword.text) '--- คืนค่าเป็น boolean
if HasAccount Then
Form1.StaShowUserName.text = me.txtUserName.text '--- อ้างถึง Cotrol ในฟอร์มแม่
me.dispose()
else
messagebox.show(" ไม่พบ Account ดังกล่าวกรุณาตรวจสอบ" ,"Error")
end if
end sub
เรียบร้อยครับ หรือ อาจจะคืนค่ามาเป็น String โดยเอา User ใน ฐานข้อมูลมาก็ได้ หรือถ้าไม่อ้างถึงแบบนี้ก็ไปทำเป็น Module ก็ได้ครับ
Special Thanks
อาจารย์สุเทพ

Splash Screen แบบ Transparent บนพื้น Window

พิ่มเติมอีกนิดสำหรับการทำ Splash Screen พอได้ได้คุณ มาโคโปโล แห่ง บอร์ด GF ได้ช่วยกรุณาตอบว่า การทำ Splash Screen แบบ Transpent นั้ต้องไปกำหนดว่า ให้กำหนด Property ของ Form ที่ชื่อว่า TransparencyKey ให้เป็น สีเดียวกับ Background แล้วมันก็จะ mask ส่วนที่เป็น Background ออกไป ผมก็ลองไปนั่งๆทำ ปรากฏว่าผมเซ็ต ใน หน้าของ Form Design แล้วไม่ได้ Splash Screen หายไปท้งหน้าเลย - -" เลยเปลี่ยนเป็น code ได้ดังนี้ :: me.transparencyKey = me.backcolor ปรากฏว่าเรียบร้อย รันได้แล้วครับ Many Thanks www.greatfriends.biz Special Thanks คุณ มาโคโปโล