วันจันทร์ที่ 30 สิงหาคม พ.ศ. 2553

Canon เปิดตัว EOS 60D

หลังจากรอดูมานานว่ากล้องซีรี่ย์ 2 หลักของ Canon ที่จะมาแทน 50D ตัวเดิมจะออกมาแบบไหนเพิ่มฟังก์ชั่นอะไรบ้าง

รู้สึกว่าไม่ค่อยจะเปลี่ยนจากตัว 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

เนื่องจากปกติผมทำงานทางด้าน IT มาก็เป็นเวลาพอสมควรละ

ซึ่งการทำงานทั่วไปก็จะเน้นไปทางด้านการพัฒนาระบบสารสนเทศซึ่งอยูในรูปแบบ In house เป็นส่วนใหญ่มีจ๊อบนอกบ้างประปราย

ข้อมูลส่วนใหญ่ที่นำมาใช้ในงานก็จะมาจากการค้นคว้า อ่านมาจาก Internet บ้าง ปรึกษาเพื่อนที่ทำงานสายเดียวกันบ้าง

แต่ปัญหาก็คือ...ช่วงหลัง ๆ รู้สึกข้อมูลจะเยอะ หัวผมก็สงสัยจะเป็นแบบ Buffer ข้อมูลล้น ลืมบ้าง อันที่เคยเขียนไว้เมื่อนานมาแล้วก็จำไม่ได้ว่าตัวเองเคยเขียน เลยมาโพสไว้ที่ Blog ดีกว่า อย่างน้อยก็ให้ได้มีเครื่องช่วยจำ คงจะเข้ามาอัพเดทเรื่อย ๆ ไม่ล่มเหมือน Blog ก่อน ๆ ที่เคยเขียนล่ะครับ ...สวัสดี

User Defined Function สำหรับแปลงตัวเลข เป็น อักษรภาษาไทย

ปกติจะเคยเห็น source code ที่ใช้สำหรับแปลงตัวเลขเป็นตัวอักษรกันเยอะแล้วนะครับ

แต่ที่ออฟฟิศผมใช้หลากหลายภาษากันมาก มีอย่างเดียวที่ใช้เหมือนกันก็คือ 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 นะครับ

PIVOT  แปลง่าย ๆ คือ Table ที่มีอยู่ จะเอาแต่ละ Row ของมันมาแปลงเป็นColumn ซะ
ตัวอย่าง
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 ภาษาไทย)

string HttpPost(string uri, string parameters)

{



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