วันจันทร์ที่ 12 พฤศจิกายน พ.ศ. 2555
กระบี่ ทัวร์เกาะห้อง
เขื่อนรัชชประภาและภูเก็ต
วันอังคารที่ 28 กันยายน พ.ศ. 2553
การสร้าง Partitioning Table บน MS Sql Server 2005
MS SQL 2005 มี feature ให้เล่น ซึ่งผมคิดว่ามีประโยชน์มาก ๆ นั่นก็คือการจัดสรรค์ข้อมูลลงไฟล์แบบกระจายโดยอัตโนมัติ หรือเรียกว่าการทำ Partioning ครับ หลักการโดยทั่วไปก็คือ การกระจาย Record ออกในแนวราบ ลง File group หลาย ๆ ไฟล์ ที่เราสร้างไว้รองรับโดยอัตโนมัติ รับรองว่าข้อมูลที่เคยมีมากมายมหาศาล ข้อมูลที่ Access แต่ละทีอืดมากมาย จะเร็วขึ้นทันตาเห็น โดยไม่ต้องทำการเพิ่มทรัพยากรด้านฮาร์ดแวร์
ขั้นตอนและวิธ๊การ ขอยกตัวอย่างจาก Adventureworks แล้วกันนะครับ
-- ทำการสร้าง partitioning functions.
-- ตัวอย่างนี้จะทำการสร้าง Partition function แยกส่วนของข้อมูลเป็น 2 ช่วงคือ ข้อมูลก่อนและหลังวันที่ '2005-01-01'
create partition function YearPF(datetime)
as range right for values ('20050101');
-- ต่อมาต้องทำการเพิ่ม file group ลงไปใน database ใครถนัด GUI ก็ใช้ GUI ได้นะครับ case นี้ใช้เป็น Command Line ดังนี้
alter database AdventureWorks add filegroup YearFG1;
alter database AdventureWorks add filegroup YearFG2;
-- ต่อมาก็ต้องทำการ add file ลงแต่ละ file group
alter database AdventureWorks add file (name = 'YearF1', filename = 'C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Data\AdvWorksF1.ndf') to filegroup YearFG1;
alter database AdventureWorks add file (name = 'YearF2', filename = 'C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Data\AdvWorksF2.ndf') to filegroup YearFG2;
-- ต่อมาก็ต้องทำการเชื่อม file group เข้ากับ partition function โดยใช้ Partitioning Scheme
create partition scheme YearPS
as partition YearPF to (YearFG1, YearFG2)
-- สุดท้ายก็ทำการสร้าง Table โดยอ้างอิงถึง Partition Scheme ที่เราทำการสร้างไว้ ข้อมูลก็จะถูกกระจายโดยอัตโนมัติ
create table PartitionedOrders
(
Id int not null identity(1,1),
DueDate DateTime not null,
) on YearPS(DueDate) --ข้อมูลจะถูกแบ่งลงแต่ละ file group โดยใช้ field 'DueDate' เป็นเงื่อนไขในการกระจาย Data
-- ทดสอบการ insert ข้อมูล
insert into PartitionedOrders values('2010-09-01')
insert into PartitionedOrders values('1900-02-07')
insert into PartitionedOrders values(getdate())
insert into PartitionedOrders values('1998-10-30')
insert into PartitionedOrders values('2005-01-01')
-- ทีนี้เรามาตรวจสอบดูว่าข้อมูลแต่ละ Record ไปหล่นใส่ partition ไหนบ้างด้วยคำสั่งนี้เลยครับ
select *, $partition.YearPF(DueDate) from PartitionedOrders
-- และสามารถดูจำนวน Partition ที่สร้างไว้ด้วยคำสั่งนี้ครับ
select * from sys.partitions where object_id = object_id('PartitionedOrders')
จากการใช้งานที่ผ่านมาสรุปว่าการ ทำ Partition Table มีประโยชน์มาก ๆ ครับ เหมาะกับฐานข้อมูลที่มี Data เยอะไฟล์บวม Partition Table ช่วยท่านได้ แต่ถ้าท่านมี Storage ที่สามารถแยก แต่ละ Partition ลงฮาร์ดดิสก์คนละก้อนได้ละก็ ประสิทธิภาพของ Database โดยรวมจะเพิ่มขึ้นแบบเห็น ๆ โดยไม่ต้องลงทุนเปลี่ยน Database Server ใหม่ครับ
วันจันทร์ที่ 30 สิงหาคม พ.ศ. 2553
Canon เปิดตัว EOS 60D
รู้สึกว่าไม่ค่อยจะเปลี่ยนจากตัว 50D ตัวเดิมเท่าไหร่แฮะ เท่าที่อ่าน ๆ ดู spec คร่าว ๆ ก็ต่างกันตรง
- Higher resolution sensor (17.9MP vs. 15.1MP)
- Accepts SD, rather than CF memory cards
- No flash sync socket
- Wireless Speedlight control
- Articulated 3:2 high resolution LCD screen
- Plastic body shell (8% weight saving)
- Standard ISO range extends to 6400, rather than 3200
- User-definable Auto ISO upper limit
- HD video recording 1080p20/25/24 or 720p60/50
- New features: in-camera raw conversion, ambience settings, creative filters etc
- No joystick, no multi-flash support, simplified top plate & info panel, only one Custom mode
- Slightly reduced customization options
- Redesigned control layout with slightly fewer buttons
- Lower burst rate
ก็ยังคงใช้ 50D ต่อไป รอจนกว่าเจ้านายที่บ้านจะอนุมัติซื้อกล้องใหม่ล่ะคร่าบบบบ
วันศุกร์ที่ 27 สิงหาคม พ.ศ. 2553
ว่าด้วยการเขียน Blog
ซึ่งการทำงานทั่วไปก็จะเน้นไปทางด้านการพัฒนาระบบสารสนเทศซึ่งอยูในรูปแบบ In house เป็นส่วนใหญ่มีจ๊อบนอกบ้างประปราย
ข้อมูลส่วนใหญ่ที่นำมาใช้ในงานก็จะมาจากการค้นคว้า อ่านมาจาก Internet บ้าง ปรึกษาเพื่อนที่ทำงานสายเดียวกันบ้าง
แต่ปัญหาก็คือ...ช่วงหลัง ๆ รู้สึกข้อมูลจะเยอะ หัวผมก็สงสัยจะเป็นแบบ Buffer ข้อมูลล้น ลืมบ้าง อันที่เคยเขียนไว้เมื่อนานมาแล้วก็จำไม่ได้ว่าตัวเองเคยเขียน เลยมาโพสไว้ที่ Blog ดีกว่า อย่างน้อยก็ให้ได้มีเครื่องช่วยจำ คงจะเข้ามาอัพเดทเรื่อย ๆ ไม่ล่มเหมือน Blog ก่อน ๆ ที่เคยเขียนล่ะครับ ...สวัสดี
User Defined Function สำหรับแปลงตัวเลข เป็น อักษรภาษาไทย
แต่ที่ออฟฟิศผมใช้หลากหลายภาษากันมาก มีอย่างเดียวที่ใช้เหมือนกันก็คือ Database ที่เป็น MS SQL
ทำอย่างไรจะได้ฟังก์ชั่นกลาง ๆ ที่สามารถเรียกใช้ได้ทุกภาษา ก็ต้องแปลงทุกอย่างให้อยู่ในภาษา SQL ล่ะครับ
ตัวอย่างนี้เป็นตัวอย่างหนึ่งที่มีการเรียกใช้บ่อย ๆ ในการพัฒนาระบบงานทั่วไปคงจะใช้กันบ่อยนะครับ
ปล. source ตัวนี้โมมาจากภาษา php
CREATE FUNCTION dbo.udf_Num2Thai (@Number1 Money)
RETURNS VARCHAR(8000)
AS BEGIN
DECLARE @number Numeric(38 , 0)
DECLARE @decimal INT
DECLARE @loops INT
DECLARE @bigLoops INT
DECLARE @counter INT
DECLARE @bigCount INT
DECLARE @mod INT
DECLARE @numbersTable TABLE (number CHAR(1), word VARCHAR(10))
DECLARE @numbersDigit TABLE (number CHAR(1), word VARCHAR(10))
DECLARE @inputNumber VARCHAR(38)
DECLARE @inputNumber1 VARCHAR(38)
DECLARE @inputDecimal VARCHAR(2)
DECLARE @charNumber CHAR(1)
DECLARE @outputString VARCHAR(8000)
DECLARE @outputString1 VARCHAR(8000)
DECLARE @outputChar VARCHAR(10)
DECLARE @outputChar1 VARCHAR(10)
DECLARE @nextNumber CHAR(1)
IF @number1 = 0 RETURN 'ศูนย์บาท'
-- insert data for the numbers and words
INSERT INTO @NumbersTable
SELECT ' ', '' UNION ALL SELECT '0', ''
UNION ALL SELECT '1', 'หนึ่ง' UNION ALL SELECT '2', 'สอง'
UNION ALL SELECT '3', 'สาม' UNION ALL SELECT '4', 'สี่'
UNION ALL SELECT '5', 'ห้า' UNION ALL SELECT '6', 'หก'
UNION ALL SELECT '7', 'เจ็ด' UNION ALL SELECT '8', 'แปด'
UNION ALL SELECT '9', 'เก้า'
INSERT INTO @NumbersDigit
SELECT '1', '' UNION ALL SELECT '2', 'สิบ'
UNION ALL SELECT '3', 'ร้อย' UNION ALL SELECT '4', 'พัน'
UNION ALL SELECT '5', 'หมื่น' UNION ALL SELECT '6', 'แสน'
SET @number = FLOOR(@number1)
SET @decimal = FLOOR((@number1 - FLOOR(@number1))* 100)
SET @inputNumber1 = CONVERT(VARCHAR(38), @number)
SET @inputDecimal = CONVERT(VARCHAR(2), @decimal)
SET @bigLoops = FLOOR(LEN(@inputNumber1) / 6) + 1
SET @mod = LEN(@inputNumber1) % 6
SET @bigCount = 1
SET @outputString = ''
WHILE @bigCount <= @bigLoops BEGIN
IF @bigCount = 1 BEGIN
SET @inputNumber = LEFT(@inputNumber1,@mod)
SET @inputNumber1 = RIGHT(@inputNumber1,LEN(@inputNumber1)-@mod)
END
ELSE BEGIN
SET @inputNumber = LEFT(@inputNumber1,6)
IF @bigCount < @bigLoops
SET @inputNumber1 = RIGHT(@inputNumber1,LEN(@inputNumber1)-6)
END
SET @outputString1 = ''
SET @counter = 1
SET @loops = LEN(@inputNumber)
SET @nextNumber = ''
WHILE 1 <= @loops BEGIN
SET @charNumber = SUBSTRING(@inputNumber,@loops,1)
SET @nextNumber = SUBSTRING(@inputNumber,@loops-1,1)
SELECT @outputChar = word FROM @NumbersTable
WHERE @charNumber = number
SELECT @outputChar1 = word FROM @NumbersDigit
WHERE CONVERT(CHAR(1),@counter) = number
IF @charNumber = '1' AND LEN(@inputNumber) > 1 AND @counter = 1 AND @nextNumber > '0'
SET @outputChar = 'เอ็ด'
IF @charNumber = '1' AND LEN(@inputNumber) >= 2 AND @counter = 2 SET @outputChar = ''
IF @charNumber = '2' AND LEN(@inputNumber) >= 2 AND @counter = 2 SET @outputChar = 'ยี่'
IF @charNumber = '0' SET @outputChar1 = ''
SELECT @outputString1 = @outputChar + @outputChar1 + @outputString1,
@counter = @counter + 1,
@loops = @loops - 1
END
IF @bigCount < @bigLoops
IF @outputString1 <> '' SET @outputString = @outputString + @outputString1 + 'ล้าน'
IF @bigCount >= @bigLoops SET @outputString = @outputString + @outputString1 + 'บาท'
SET @bigCount = @bigCount + 1
END
-- Decimal
IF LEN(@inputDecimal)= 1 SET @inputDecimal = '0' + @inputDecimal
SET @inputNumber = @inputDecimal
SET @counter = 1
SET @loops = LEN(@inputNumber)
SET @outputString1 = ''
SET @nextNumber = SUBSTRING(@inputNumber,@loops-1,1)
WHILE 1 <= @loops BEGIN
SET @charNumber = SUBSTRING(@inputNumber,@loops,1)
SELECT @outputChar = word FROM @NumbersTable
WHERE @charNumber = number
SELECT @outputChar1 = word FROM @NumbersDigit
WHERE CONVERT(CHAR(1),@counter) = number
IF @charNumber = '1' AND LEN(@inputNumber) > 1 AND @counter = 1 AND @nextNumber > '0'
SET @outputChar = 'เอ็ด'
IF @charNumber = '1' AND LEN(@inputNumber) >= 2 AND @counter = 2 SET @outputChar = ''
IF @charNumber = '2' AND LEN(@inputNumber) >= 2 AND @counter = 2 SET @outputChar = 'ยี่'
IF @charNumber = '0' SET @outputChar1 = ''
SELECT @outputString1 = @outputChar + @outputChar1 + @outputString1,
@counter = @counter + 1,
@loops = @loops - 1
END
IF @inputDecimal = '00'
SET @outputString = @outPutString + 'ถ้วน'
ELSE SET @outputString = @outputString + @outputString1 + 'สตางค์'
RETURN @outputString -- return the result
END
Using PIVOT and UNPIVOT สำหรับ MS SQL Server นะครับ
ตัวอย่าง
USE AdventureWorks;
GO
SELECT VendorID, [164] AS Emp1, [198] AS Emp2, [223] AS Emp3, [231] AS Emp4, [233] AS Emp5
FROM
(SELECT PurchaseOrderID, EmployeeID, VendorID
FROM Purchasing.PurchaseOrderHeader) p
PIVOT
(
COUNT (PurchaseOrderID)
FOR EmployeeID IN
( [164], [198], [223], [231], [233] )
) AS pvt
ORDER BY VendorID
ผลลัพธ์ที่ไ้ด้จะเป็นแบบข้างล่างนี้
VendorID Emp1 Emp2 Emp3 Emp4 Emp5
1 4 3 5 4 4
2 4 1 5 5 5
3 4 3 5 4 4
4 4 2 5 5 4
5 5 1 5 5 5
ส่วนในทางกลับกัน ถ้าข้อมูลที่มีอยู่เก็บอยู่ในรูปแบบ Column
แล้ว User ไม่พอใจอยากให้มันแสดงเป็น Row แทนซะงั้น (ความพอดีไม่มีในโลก)
ไม่เป็นไร ให้ Unpivot ช่วย ตามตัวอย่าง
--Create the table and insert values as portrayed in the previous example.
CREATE TABLE pvt (VendorID int, Emp1 int, Emp2 int,
Emp3 int, Emp4 int, Emp5 int)
GO
INSERT INTO pvt VALUES (1,4,3,5,4,4)
INSERT INTO pvt VALUES (2,4,1,5,5,5)
INSERT INTO pvt VALUES (3,4,3,5,4,4)
INSERT INTO pvt VALUES (4,4,2,5,5,4)
INSERT INTO pvt VALUES (5,5,1,5,5,5)
GO
--Unpivot the table.
SELECT VendorID, Employee, Orders
FROM
(SELECT VendorID, Emp1, Emp2, Emp3, Emp4, Emp5
FROM pvt) p
UNPIVOT
(Orders FOR Employee IN
(Emp1, Emp2, Emp3, Emp4, Emp5)
)AS unpvt
GO
ผลลัพธ์ที่ได้ ก็จะออกมาตามที่ท่าน User ต้องการครับ
VendorID Employee Orders
1 Emp1 4
1 Emp2 3
1 Emp3 5
1 Emp4 4
1 Emp5 4
2 Emp1 4
2 Emp2 1
2 Emp3 5
2 Emp4 5
2 Emp5 5
...
หวังว่าพอจะอ่านเข้าใจ เขียนแบบสั้น ๆ ห้วน ๆ ตามประสาโปรแกรมเมอร์ขรี้เกียจ จบดีกว่า..
Web service AJAX Cascade dropdown ตำบล อำเภอ จังหวัด
ส่วนแรก หน้า aspx
<ajaxToolkit:ToolkitScriptManager runat="Server" EnableScriptGlobalization="true"EnableScriptLocalization="true" ID="ScriptManager1" />
<asp:DropDownList ID="DropDownList1" runat="server"></asp:DropDownList>
<asp:DropDownList ID="DropDownList2" runat="server"></asp:DropDownList>
<asp:DropDownList ID="DropDownList3" runat="server">
</asp:DropDownList><br />
<ajaxToolkit:CascadingDropDown ID="CascadingDropDown1" runat="server" TargetControlID="DropDownList1"
ServicePath="CommonService.asmx"
ServiceMethod="GETPROVINCE"
Category="Province"
PromptText="เลือกจังหวัด"
LoadingText="กำลังอ่านข้อมูล...">
</ajaxToolkit:CascadingDropDown>
<ajaxToolkit:CascadingDropDown ID="CascadingDropDown2"
runat="server" TargetControlID="DropDownList2"
ServicePath="CommonService.asmx" ServiceMethod="GETAMPHUR"
ParentControlID="DropDownList1"
Category="Amphur"
PromptText="เลือกอำเภอ"
LoadingText="กำลังอ่านข้อมูล..." >
</ajaxToolkit:CascadingDropDown>
<ajaxToolkit:CascadingDropDown ID="CascadingDropDown3"
runat="server"
TargetControlID="DropDownList3"
ServicePath="CommonService.asmx"
ServiceMethod="GETTUMBOL"
ParentControlID="DropDownList2"
Category="GETTUMBOL"
PromptText="เลือกตำบล"
LoadingText="กำลังอ่านข้อมูล..." >
</ajaxToolkit:CascadingDropDown>
ส่วนที่สอง ส่วนของ Web Service
public class CommonService : System.Web.Services.WebService
{
public CommonService()
{
//Uncomment the following line if using designed components
//InitializeComponent();
}
public string ConnStr = ConfigurationManager.ConnectionStrings["TestDB"].ConnectionString;
[WebMethod(EnableSession = true)]
public CascadingDropDownNameValue[] GETPROVINCE(string knownCategoryValues, string category)
{
SqlConnection myConnection = new SqlConnection(ConnStr);
SqlCommand myCommand = new SqlCommand("select '1',changwatname,provinceid from changwat where provinceid= @provinceid union select '2',changwatname,provinceid from changwat", myConnection);
myCommand.CommandType = CommandType.Text;
myCommand.Parameters.AddWithValue("@provinceid", "32" /*provinceid*/);
myConnection.Open();
List<CascadingDropDownNameValue> values = new List<CascadingDropDownNameValue>();
using (SqlDataReader reader = myCommand.ExecuteReader())
{
while (reader.Read())
{
values.Add(new CascadingDropDownNameValue((string)reader["changwatname"], reader["provinceid"].ToString()));
}
myConnection.Close();
return values.ToArray();
}
}
[WebMethod]
public CascadingDropDownNameValue[] GETAMPHUR(string knownCategoryValues, string category)
{
StringDictionary kv = CascadingDropDown.ParseKnownCategoryValuesString(
knownCategoryValues);
int Provinceid;
if (!kv.ContainsKey("Province") ||
!Int32.TryParse(kv["Province"], out Provinceid))
{
return null;
}
SqlConnection myConnection = new SqlConnection(ConnStr);
SqlCommand myCommand = new SqlCommand("select '1',amphurname,cityid from amphur where provinceid= @provinceid and cityid is not null /*union select '2',amphurname,cityid from amphur where cityid is not null*/", myConnection);
myCommand.CommandType = CommandType.Text;
myCommand.Parameters.AddWithValue("@provinceid", Convert.ToString(Provinceid)); //"01" /*districtid*/);
myConnection.Open();
List<CascadingDropDownNameValue> values = new List<CascadingDropDownNameValue>();
using (SqlDataReader reader = myCommand.ExecuteReader())
{
while (reader.Read())
{
values.Add(new CascadingDropDownNameValue((string)reader["amphurname"], reader["cityid"].ToString()));
}
}
return values.ToArray();
}
[WebMethod]
public CascadingDropDownNameValue[] GETTUMBOL(string knownCategoryValues, string category)
{
StringDictionary kv = CascadingDropDown.ParseKnownCategoryValuesString(
knownCategoryValues);
int Amphurid;
int Provinceid;
string a;
string b;
if (!kv.ContainsKey("Amphur"))
{
return null;
}
b = kv["Amphur"];
a = kv["Province"];
SqlConnection myConnection = new SqlConnection(ConnStr);
SqlCommand myCommand = new SqlCommand("select '1',tumbolname,districtid from tumbol where provinceid = @provinceid and cityid= @cityid ", myConnection);
myCommand.CommandType = CommandType.Text;
myCommand.Parameters.AddWithValue("@provinceid", Convert.ToString(a));
myCommand.Parameters.AddWithValue("@cityid", Convert.ToString(b)); //"01" /*districtid*/);
myConnection.Open();
List<CascadingDropDownNameValue> values = new List<CascadingDropDownNameValue>();
using (SqlDataReader reader = myCommand.ExecuteReader())
{
while (reader.Read())
{
values.Add(new CascadingDropDownNameValue((string)reader["tumbolname"], reader["districtid"].ToString()));
}
}
return values.ToArray();
}
ฟังก์ชั่น C# สำหรับ WebRequest ผ่าน http (แก้ปัญหาการ Post ภาษาไทย)
{
// parameters: name1=value1&name2=value2
WebRequest webRequest = WebRequest.Create(uri);
//string ProxyString =
// System.Configuration.ConfigurationManager.AppSettings
// [GetConfigKey("proxy")];
//webRequest.Proxy = new WebProxy (ProxyString, true);
//Commenting out above required change to App.Config
webRequest.ContentType = "application/x-www-form-urlencoded";
webRequest.Method = "POST";
//แก้ปัญหาการส่งภาษไทยแล้วกลายเป็นภาษายึกยือ
Encoding thaiEnc = Encoding.GetEncoding("iso-8859-11");
byte[] bytes = thaiEnc.GetBytes(parameters);
Stream os = null;
try
{ // send the Post
webRequest.ContentLength = bytes.Length; //Count bytes to send
os = webRequest.GetRequestStream();
os.Write(bytes, 0, bytes.Length); //Send it
}
catch (WebException ex)
{
MessageBox.Show(ex.Message, "HttpPost: Request error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
if (os != null)
{
os.Close();
}
}
try
{ // get the response
WebResponse webResponse = webRequest.GetResponse();
if (webResponse == null)
{ return null; }
StreamReader sr = new StreamReader(webResponse.GetResponseStream());
return sr.ReadToEnd().Trim();
}
catch (WebException ex)
{
MessageBox.Show(ex.Message, "HttpPost: Response error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
return null;
}
}
ฟังก์ชั่นตรวจสอบเลขที่บัตรประจำตัวประชาชน
ใช้คู่กะ Customvalidator ตามนี้
ฝั่ง code behind
protected void CheckIDCard(object source, ServerValidateEventArgs args)
{
//args.IsValid = (args.Value.Length >= 8);
int pin = 0;
int j = 13;
int pin_num = 0;
if (args.Value.ToString() == "")
{
args.IsValid = false;
return;
}
bool ChkPinID = true;
if (ChkPinID == false) { args.IsValid = false; return; }
if (args.Value.ToString().Length == 13)
{
for (int i = 0; i < args.Value.Length; i++)
{
if (i != 12)
{
pin = Convert.ToInt16(args.Value.ToString().Substring(i, 1)) * j + pin;
}
j--;
}
pin_num = (11 - (pin % 11)) % 10;
if (Convert.ToInt16(args.Value.ToString().Substring(12, 1)) != pin_num)
{
args.IsValid = false;
return;
}
}
else
{
args.IsValid = false;
return;
}
args.IsValid = true;
return;
}
ฝั่ง webpage
<asp:TextBox ID="txtICard" runat="server" MaxLength="13" Width="100px"></asp:TextBox>
<asp:CustomValidator ID="validIDCard" runat="server" ControlToValidate="txtICard"
ErrorMessage="เลขที่บัตรประชาชนไม่ถูกต้อง" SetFocusOnError="True" ValidateEmptyText="True"
OnServerValidate="CheckIDCard"></asp:CustomValidator>
วันอังคารที่ 2 กุมภาพันธ์ พ.ศ. 2553
สิมิลัน วันฟ้าใส
วันพฤหัสบดีที่ 1 มกราคม พ.ศ. 2552
น้ำตกวังก้านเหลือง อำเภอชัยบาดาล ลพบุรี
ปีใหม่ขับรถเล่นไปเยี่ยมน้องที่ลพบุรี เลยแวะไปน้ำตกใกล้ ๆ บ้านที่ลำนารายณ์
น้ำตกสีเขียว ๆ ฟ้า ๆ สีแปลกดี นักท่องเที่ยวยังไม่ค่อยรู้จัก
ขนาดหยุดยาวปีใหม่ไปก็ยังไม่เห็นมีคนเข้าไปเที่ยว เงียบดี
วันศุกร์ที่ 5 ธันวาคม พ.ศ. 2551
เดินเรื่อยเปื่อยรอบเกาะรัตนโกสินทร์
วันที่ 5 ธันวาคม 2551 ฉลองวันพ่อด้วยการเดินเล่นรอบ ๆ เกาะรัตนโกสินทร์ เดินจริง ๆ ตั้งแต่ เที่ยงยันสองทุ่ม ขาลาก
เดินเก็บภาพไปเรื่อย ๆ ช่วงค่ำ ๆ ก็มีจุดเทียนชัยถวายพระพร แต่ไม่นึกว่าจะมีพลุด้วยแฮะ ไม่ได้หาทำเลถ่ายพลุเลย เสียดาย ๆ
**อุปกรณ์ การนำเที่ยว
Canon EOS 300D เก่าเก็บ ฉลองครบรอบ 4 ปีแว้ววว
Sigma 10-20 และขาตั้ง+สายลั่นชัตเตอร์
วันพุธที่ 18 มิถุนายน พ.ศ. 2551
[FLASH] Video Streaming แบบ flv -Scrubber กันเถอะ
ฝั่ง Server ต้องมี
1. Web Server ได้ทั้ง IIS และ Apache แต่ทางผู้พัฒนาแนะนำ lighttpd ซึ่งไม่รู้คืออะไร ผมไม่เคยใช้ เอาเป็นว่าใช้ IIS 6.0 ก็ได้ละกัน
2. Flash Video Player ตอนนี้จะใช้ flv -Scrubber เพราะใช้ง่ายแต่ที่สำคัญฟรี ดาวน์โหลด ->> Download latest version of FLV-Scrubber 3.0
3. ไฟล์ flv ซึ่งเป็น file ที่จะเอามาทำ streaming
เอาทั้ง 2 ไฟล์ไปไว้ที่เดียวกัน แล้วก็เขียน code html มาซักตัวทดสอบดูครับ
ส่วนของ Code Html
<object id="FLVScrubber" width="450" height="253" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0">
<param name="movie" value="FLVScrubber.swf"/>
<param name="bgcolor" value="#000000"/>
<!--<param name="allowScriptAccess" value="sameDomain"/> -->
<param name="allowFullScreen" value="true"/>
<param name="flashVars" value="file=TPBS.flv"/>
<embed src="FLVScrubber.swf" bgcolor="#000000" width="450" height="253" name="FLVScrubber" allowScriptAccess="sameDomain" allowFullScreen="true"flashVars="file=TPBS.flv" type="application/x-shockwave-flash" pluginspage="http://www.adobe.com/go/getflashplayer"></object>
</body>
</html>
ในที่นี้ file flv ของผมชื่อ TPBS.flv ซึ่งเก็บอยู่ใน path เดียวกะ flash video player ครับ เวลาเรียกก็เรียกได้ตรง ๆ ถ้าทำสำเร็จก็จะขึ้นหน้าตาดังรูปข้างล่าง..จบ
วันพุธที่ 23 เมษายน พ.ศ. 2551
[NET] สลับสี Row บน Datagrid
protected
void dtgShowupload_RowCreated(object sender, GridViewRowEventArgs e){
if (e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.Attributes.Add("onmouseover", "this.style.backgroundColor='#CCCCCC';");
if (e.Row.RowIndex % 2 == 0)
{
e.Row.Attributes.Add("onmouseout", "style.backgroundColor='#EFF3FB'"); // หาสีที่ใกล้เคียงเองเนอะ....
}
else
{
e.Row.Attributes.Add("onmouseout", "style.backgroundColor='White'");
}
}
}
วันจันทร์ที่ 7 เมษายน พ.ศ. 2551
[MS] How to MCPD
ถ้าอยากจะสอบ MCPD(Microsoft Certified Professional Developer) ก็ต้องไปอ่านรายละเอียดให้เข้าใจว่าต้องศึกษาอะไรไว้บ้าง สอบตัวไหนบ้าง
ก่อนจะเป็น MCPD ต้องได้ MCTS(Microsoft Certified Technology Specialist) ก่อน มีสามใบ เลือกเอาอย่างใดอยางหนึ่ง
- MCTS Web Applications
- MCTS Windows Applications
- MCTS Distributed Applications
วิชาที่ต้องสอบสายละ 2 วิชา เป็นวิชาหลักวิชานึงแล้วก็วิชาเลือกตามสายวิชานึง รวมสำหรับ MCTS มีวิชาทั้งหมดแล้ว 4 วิชา
ส่วน MCPD มีสามแบบเช่นกัน คือ
- MCPD Web Developer
- MCPD Windows Developer
- MCPD Enterprise Application Developer
แบบ 1 กับ 2 สอบแค่ 3 วิชา แต่แบบที่ 3 สอบ 5 วิชา อันนี้นับรวมกับสอบ MCTS ด้วย คิดง่ายๆก็ต่อเฉพาะทางอีกใบนั่นแหละ
สำหรับ MCPD Enterprise Application Developer ก็ต้องผ่านการสอบของ MCTS หมดทั้ง 4 วิชาเลย
พูดง่ายๆว่าต้องเป็น MCTS ทุกสาขาก่อนนั่นแหละ แล้วก็สอบอัพเกรดขึ้นไปอีกหนึ่งที รวมเป็น 5 วิชา แต่ถ้าจะเป็น MCPD ก่ออันนึงแล้วค่อยตามเก็บที่เหลือมันจะต้องสอบ 6 วิชา
วิชาอะไรเป็นอะไร สายไหนต้องสอบอะไรบ้าง ก็เข้าไปเลือกดูได้เลยตามข้างล่าง
แผนภูมิ
วันพฤหัสบดีที่ 27 มีนาคม พ.ศ. 2551
[NET] การส่ง QueryString โดยใช้ Datagrid
เพิ่มไอ้นี่เข้าไป
<asp:HyperLinkField
DataNavigateUrlFields="CompanyName,CustomerID"
DataNavigateUrlFormatString="GetData.aspx?x1={0}&x2={1}"
DataTextField="CompanyName" />
เท่านี้ก็ได้แว้ว
วันพุธที่ 12 มีนาคม พ.ศ. 2551
[SQL] Count String Occurrence Function
CREATE FUNCTION [dbo].[ufn_CountString]
( @pInput VARCHAR(8000), @pSearchString VARCHAR(100) )
RETURNS INT
BEGIN
RETURN (LEN(@pInput)-LEN(REPLACE(@pInput, @pSearchString, '')))/LEN(@pSearchString)
END
GO
[NET] ไม่ต้องการ ให้วน process เวลา กด refresh หรือ back
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not Page.IsPostBack Then
Session("update") = Server.UrlEncode(System.DateTime.Now.ToString())
End If
Protected Sub Page_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreRender
'/// ถ้าเป็นการกดปุ่ม Refresh ที่ Browser ค่าใน ViewState("update") จะไม่ถูก Render ลงใน Client
'/// ทำให้ตอนที่ compare เวลาจะไม่ตรงกัน
ViewState("update") = Session("update")
End Sub
Protected Sub btn_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btn.Click
If Session("update").ToString() = ViewState("update").ToString() Then
'/// เพิ่มข้อมูลลงใน Db
Session("update") = Server.UrlEncode(System.DateTime.Now.ToString())
End If
วันพฤหัสบดีที่ 15 กุมภาพันธ์ พ.ศ. 2550
เรื่องลับ ๆ ของมหาวิทยาลัยขอนแก่น ตลกดี คัดมาให้อ่าน
1. มข.มีพื้นที่ใหญ่มากๆ เกือบ 6000 ไร่ แต่เกือบ 80% ดันเป็นพื้นที่ป่า
2. อคร. (ย่อมาจาก อาคารเรียนโคตรร้อน) คณะวิทย์เป็นตึกที่โทรมมาก ไม่มีแอร์ 70% ของเด็กที่เรียน or-chem คาบบ่าย ที่ตึกนี้ล้วนแต่คิดในใจว่า "ฆ่ากรูซะ"
3. ทุกคณะจะมาเรียน Eng ที่คณะมนุษย์ โดยจะแบ่งเป็นหลายๆ sec ตามระดับความไฮโซ ที่คณะผม เชื่อกันว่าเด็กที่เรียน sec 6 หมายถึง "พูด eng ได้คล่องยังกับเมียฝรั่ง" ส่วนเด็กที่เรียน sec 24 หมายถึง "แค่ท่อง A - Z ได้ก็เก่งแล้ว"
4. ห้องสมุดกลางของ มข. มี 6 ชั้น แต่ตอนออกจากห้องสมุด หลายๆ คนมักจะหลงเดินลงไปถึงชั้น 1 ซึ่งเป็นชั้นใต้ดิน (จริงๆ แล้วทางออกอยู่ชั้น 2)
5. รสนิยมการดื่มเหล้าของเด็ก มข. มี 2 แบบ คือ พวกที่เปิด Red ที่ U-bar กับพวกที่ตั้งวงสุราขาวหลังมอ
6. เท่าที่ได้ยินมา 40% ของเด็กที่อยู่หอพยาบาลไม่ใช่เด็กคณะพยาบาล
7. คนที่ไปวิ่งบึงสีฐานมีจุดประสงค์เพื่อ "สร้างเสริมสุขภาพ" ในขณะที่คนที่ไปวิ่งสระพลาสติกมีจุดประสงค์เพื่อ "เสาะหาอาหารตา"
8. ที่หลังคาเหล็ก ทุกๆเย็น จะมีคนมาเต้น แอโรบิค โดย มีเพียง ร้อยละ 2 เท่านั้น ที่ "เต้นเพื่อสุขภาพจริงๆ" ซึ่งอีก ร้อยละ 90 นั้น "เต้นเพื่อเอาเกรด A วิชาพละ" ส่วนที่เหลืออีกร้อยละ 8 ที่ไปเต้นนั้น จะมีจุดประสงค์ คล้ายๆกับคนที่ไปวิ่งสระพลาสติก
9. "สระพลาสติก" ของ มข. ถูกตั้งชื่อนี้มาเพราะมีพลาสติกบุรองอยู่ข้างใต้ สระแห่งนี้ "ห้ามปล่อยสัตว์น้ำ" และ "ห้ามนำสุนัขไปอาบน้ำในสระ"
10. 80% ของคนที่รับประทานอาหาร ที่ "โรงชาย" เป็น ผู้หญิง กับ ผู้หญิงประเภท 2
11. "ตึกหลอด" อยู่คณะวิทย์ เป็นตึกที่เรียน Lab แล้วสนุกที่สุด (มีอุปกรณ์ฟิสิกส์แปลกๆ ยั้วเยี้ย เต็มไปหมด)
12. มข. เป็นมหาลัยที่มีหอพักนักศึกษา มากที่สุด และค่าหอก็ถูกที่สุดด้วย
13. คุณต้องทำกิจกรรมอย่างน้อยเดือนละ 10 วัน ถึงจะมีสิทธิ์เข้าอยู่หอในของ มข.
14. ยามที่ มข. แต่งตัวคล้าย ตำรวจสายตรวจมากๆ ต้องแยกออกจากกันให้ดีๆ
15. ฤดูร้อนที่ มข. อุณหภูมิ จะร้อนกว่า 40 องศา ส่วนฤดูหนาว อุณหภูมิ จะลดต่ำลงถึง 20 องศา ดังนั้น เด็ก มข. หลายคนจึงกระเสือกกระสนไปอยู่หอนอก เพียงเพราะต้องการ แอร์กับเครื่องทำน้ำอุ่น
16. มข. มี โรงเรียนสาธิตถึง 2 แห่ง คือ สาธิตศึกษาศาสตร์ฯ กับสาธิตมอดินแดงฯ
17. complex เป็นศูนย์รวมอาหารและบริการของนักศึกษาที่นี่ ที่นี่เป็นแหล่งรวมสถาบันติวของเด็ก มข. ที่เปิดอย่างลับๆ (รุ่นพี่เปิดติวรุ่นน้องนั่นแหละ) เป็นที่ซุ่มอ่านหนังสือในยามดึกสงัดของคืนวันก่อนสอบ และที่น่าสนใจคือ บอร์ดติดประกาศของ complex ที่มีประกาศแทบทุกชนิดมาติดเอาไว้ตั้งแต่ ดินสอหาย สุนัขหาย สามีหายออกจากบ้าน ประกาศขายมือถือ ขายสกู๊ตเตอร์ ขาย vcd ซีรี่ส์หนังเกาหลี ประกาศห้องว่างให้เช่า แต่ที่ผมว่าเด็ดสุด ก็ตรงที่มีประกาศจับคนร้ายขโมยกระเป๋าตังค์พร้อมเปิดเผยหน้าตาด้วยนี่แหละ
18. "ตึกเพียรวิจิตร" เป็นสมบัติของคณะวิดวะ ที่มีคนเข้าไปอ่านหนังสือมากพอๆกับหอสมุดกลาง แต่อีกที่หนึ่งที่มีคนไปอ่านหนังสือมากพอๆกัน คือ "โรงอาหารคณะแพทย์"
19. ประตูทางเข้า มข. ใหญ่สุดในประเทศไทย
20. สาย 8 เป็นรถประจำทางที่วิ่ง เข้า-ออก มข. ซึ่ง พขร. ของสาย 8 ส่วนใหญ่ขับรถได้....(เติมเอาเอง).....มาก คือจะขับรถกลางเส้นถนนด้วยความเร็ว 20 km/ชั่วโมง
21. วิ่งรอบ มข. 5 รอบ = วิ่งจากขอนแก่นไปอุดรฯ
22. "สระชนเห็นชอบ" เป็นสระว่ายน้ำที่ pop ที่สุดของ มข. แต่ไม่มีใครไปใช้บริการ เพราะ-----> ไม่มีน้ำในสระ
23. เค้าบอกมาว่า พี่ชายภราดร เป็น อาจารย์ สอนเทนนิส ที่ มข.
24. เสื้อครุย ของ มข. ตอนรับปริญญา เป็นสีขาวนะ
25. "สะพานขาว" เป็นสะพานยาวๆ ข้างสระพลาสติก มีเจ้าที่ชื่อ "เจ๊ขาว" เป็นผู้หญิงผมยาวๆ ใส่ชุดสีขาว เจ๊แกชอบออกมาทักทายเด็กที่ ขับมอไซด์ ผ่านสะพานตอนดึกๆ
26. วิ่งกลั้นหายใจข้ามสะพานขาว แล้วจะขอพรอะไรก้ได้ 1 ข้อ
27. จากข้อ 27. ถ้าคุณขี้เกียจวิ่ง จะเปลี่ยนเป็นกลั้นหายใจ ขับมอไซด์ ด้วยความเร็ว ไม่เกิน 40km/ชั่วโมง ก็ไม่ว่ากัน
28. รุ่นพี่คณะวิดวะ เล่าให้ฟังว่า แต่ก่อน มข. ก็คือพื้นที่แห้งแล้งดีๆ นี่เอง แต่คณะวิดวะ สมัยนั้นรับน้องโดยการให้น้องปลูกต้นไม้คนละ 1 ต้น (บนพื้นดินแล้งๆ นี่แหละ) แล้วดูแลอย่าให้มันตาย ไม่งั้นโดนทำโทษ จนในที่สุด เดี๋ยวนี้หันไปมองทางไหนใน มข. ก็เจอแต่ป่า
29. คณะที่ก่อตั้งพร้อมๆ กับ มข. คือ เกษตร และ วิดวะ
30. ไก่ย่าง U-center เป็นไก่ย่างที่อร่อยที่สุดในโลก
31. ละครคณะวิทยาการสนุกที่สุด ละครคณะมนุษย์นักแสดงหน้าตาดีที่สุด ละครคณะวิดวะมุกตลกฮาที่สุด ส่วนละครคณะแพทย์ขายบัตร VIP แพงที่สุด (แต่ก็คุ้มค่านะ)
32. กังสดาล ถือเป็นแหล่งที่รวบรวมอาหาร หอนอก และสาวเภสัช เอาไว้มากที่สุดใน มข.
33. กังสดาล แบ่งเป็น กังบน กับ กังล่าง สมัยก่อนกังบนขายแต่อาหารแพงๆ เน้นรสชาติ ส่วนกังล่างขายอาหารถูกๆ เน้นปริมาณกับคุณภาพ แต่เดี๋ยวนี้ เนื้อที่ กังบน โดนทุบเอาไปสร้างถนนเกือบหมดแล้ว ทำให้ร้านอาหารที่กังบนส่วนใหญ่ ย้ายลงมาเบียดกับร้านอาหารที่ กังล่าง ซะงั้น
34. U-center คือแหล่งรวมอาหาร ร้านเกม และร้านการ์ตูน ของ มข.
35. ที่ U-center จะมีซอยๆ หนึ่ง ชื่อว่า "ซอยโลกีย์" ไม่ขออธิบายนะ ชื่อมันฟ้องอยู่แล้ว
36. ก๋วยเตี่ยวดู๋ดี๋ที่ซอย โลกีย์ อร่อยกว่าทุก สาขา ใน มข.
37.คุณ สามารถดูหนังเกาหลี 3 เรื่อง 20 บาท ได้ที่ U-center
38. คุณสามารถร้องเกะชั่วโมงละ 50 บาท ได้ที่ U-center
39. อย่าสับสนระหว่าง U-center กับ U-bar เพราะมันไม่เกี่ยวข้องกันเลย U-bar ไม่ได้อยู่ในมอนะ อย่าเข้าใจผิด
40. โรงพยาบาลศรีนครินทร์เป็นที่ตั้งของคณะแพทย์ มข. เป็นโรงพยาบาลที่ใหญ่ที่สุดในอีสาน มีคนไข้เยอะมากจนถึงขั้นต้องเอาเสื่อไปปูนั่งที่ลานจอดรถ เพื่อรอเข้าห้องตรวจโรค
41. เค้าเล่ากันว่า อย่ามองจั่วของตึกคณะ ถาปัด ขณะขับรถ เพราะมันจะเกิดอุบัติเหตุ
42. เจ๊พร เป็นแหล่งรวม ร้านอาหาร ร้านนม และของกุ๊กกิ๊ก ของ มข.
43. ร้าน 25th copy เป็นร้านถ่ายเอกสาร ตั้งอยู่ที่เจ๊พร ถ้าเกิดตำรวจลองเข้ามาตรวจค้นจริงๆ มีหวังเจ้าของร้านโดนค่าปรับโทษฐานละเมิดลิขสิทธิ์เป็น ร้อยล้าน แน่ๆ เพราะเจ๊แกเล่นเอาหนังสือเกือบทั้งห้องสมุด + ข้อสอบเก่าของทุกคณะ ทุกชั้นปี มา copy ขายเองหมด
44.มี Virus คอมพิวเตอร์ ชื่อ "clip VDO" ระบาดหนักในมข. เมื่อปี 2546 จนถึงขั้น พบไวรัสตัวนี้ในแฮนดี้ไดรฟ์และคอมทุกเครื่องของ นักศึกษา มข.
45. ที่ มข. มีร้านดอกไม้วางแผงขายที่กังสดาล วันธรรมดา กุหลาบดอกละ 5 บาท วันวาเลนไทน์ กุหลาบดอกละ 50 ส่วนวันรับปริญญา ซื้อกุหลาบ 1 ช่อ = ค่าเช่ารถสาย 8 วิ่งรอบขอนแก่น
46. ก่อนจะมาเรียน มข. หัดขับ ยานพาหนะ ให้ได้ซักอย่างก่อนจะดีมาก เอาแค่จักรยานก็ยังดี
47. ร้านตัดผมที่ มข. ที่ดังๆ มี 2 ที่คือ complex กับ BigCut โดยค่าตัดผมที่ complex หัวละ 40 บาท ส่วนที่ BigCut หัวละ 200 บาท ซึ่งสุดท้ายแล้ว ผู้ที่ใช้บริการทั้ง 2 ร้านนี้ ต่างก็ต้องลงเอยที่ทรง สกินเฮ้ดด้วยกันทั้งสิ้น
48. "เจ้าพ่อมอดินแดง" คือสิ่งศักดิ์สิทธิ์ที่เป็นที่เคารพของชาว มข. มีคนนำช้างกับม้ามาถวายท่านเจ้าพ่อ เฉลี่ย วันละ 100 ตัว
47. คณะทุกคณะ ย่อมจะต้องมีห้องประชุมใหญ่เป็นของตนเอง แต่เท่าที่เห็น เวลามหาลัยจะจัดกิจกรรมอะไรซักที ถ้าไม่ใช้ห้องประชุมของคณะศึกษาศาสตร์ก็ต้องห้องประชุมของสัดแพด
48. "หลังเต่า" คือหอประชุมใหญ่ของ มหาลัย ตั้งอยู่ริมบึงสีฐาน หน้ามอ เป็นหอประชุมที่รูปทรงสวยมากในความคิดของผม ถ้าสีมันซีดลงอีกนิด เวลามองไกลๆ คงจะคล้ายๆโอเปร่าเฮาส์ที่อยู่ในออสเตรเลีย หอประชุมนี้จะเปิดใช้ในงานสำคัญๆ เช่น ปฐมนิเทศนักศึกษา ไหว้ครู บายศรีสู่ขวัญ พระราชทานปริญญาบัตร และงาน EXPO เป็นต้น
49. ท่า boom ของ มข. ถือเป็นท่า boom ที่มีประสิทธิภาพมาก เพราะคุณจะได้ออกกำลังกายทั้งหน้าท้อง สะโพก ต้นขา ลำคอ และหลัง
50. สีประจำ มข. คือสีอิฐ
51. ดอกไม้ประจำ มข. คือ ดอกกัลปพฤกษ์ ซึ่งทุกวันนี้เพื่อนผมบางคนยังถามผมว่า "ไอ้ดอกนี่มันปลูกอยู่ส่วนไหนของมอเราวะ?"
52. ภายใน มข. มีร้าน seven-eleven ถึง 10 สาขา
53. ร้าน seven-eleven สาขากังสดาล ถือเป็นอะไรที่ไร้สาระที่สุดในโลก เพราะดันมี 2 สาขามาเปิดห่างกันแค่ 10 เมตร
54. นิตยสาร Boom comic เป็นนิตยสารสุดฮิตมากใน มข. ฮิตขนาดไหนน่ะเหรอ ก็ขนาดร้านการ์ตูนที่ U-center สั่งมาอาทิตย์ละร้อยๆเล่ม ยังสามารถขายได้หมดภายในวันเดียวน่ะสิ
55. ที่ complex ขายข้าวแกงหลากหลาย พอๆกับบุฟเฟต์ โรงแรมโซฟิเทล
56. ไม่มีปีใดที่ freshy มข. จะผ่านเชียร์กลางโดยไม่ได้ยินเสียงร้องไห้ แห่งพลังสามัคคี
57. เพลงมาร์ช มข. เพราะจริงๆนะ
58. สนามกีฬากลาง มข. เป็นสนามที่ออกแนว "สาธารณะ" มากๆ หลายเดือนก่อน เห็นโรงเรียนอนุบาลที่ไหนก็ไม่รู้ มาขอใช้สนามกีฬากลาง มอเรา แข่งกีฬาสี ซะงั้น
59. จำนวนนักศึกษา มข. ทั้งหมดมี 50,000 คน สามารถเกณฑ์เอานักศึกษา มข.ไปลงชื่อขับไล่รัฐมนตรีได้สบายๆ เลยล่ะ
60. ร้าน CSK เป็นร้านเน็ตที่ดัง และใหญ่มาก ใน มข. ถ้าคุณไม่รู้มาก่อนว่านี่คือร้านเน็ต คุณจะต้องนึกว่าที่นี่คือ บริษัท IBM ชัวร์
61. ถ้าคุณสังเกตดีๆ ด่านตรวจจับหมวกกันน็อกใน มข. ทุกด่าน ทั้งตรงทางเข้ากังสดาล ทางเข้า U-center หรือ ตรงทางออกฝั่งเจ้าพ่อมอดินแดง จะต้องมีถนนเล็กๆ ตัดผ่านก่อนจะถึงด่านตรวจ เพื่อให้เราขับอ้อมหนีตำรวจเสมอ
62. หอ 27 ผีดุสุดๆๆๆ ส่วนหอ 25 สาวๆ น่ารักสุดๆ
63. ค่าเทอมของ มข. 1 หน่วยกิต แพงกว่า รามฯ 35 บาท
เครดิต K.To_harm_never แห่งเวป pantip





































