Month: January 2017

  • การตั้งค่า Font เริ่มต้นใน Word ไม่ต้องคอยเปลี่ยนทุกครั้ง

    สำหรับท่านที่อาจจะต้องพิมพ์เอกสารราชการบ่อยๆ ซึ่งต้องใช้ TH Sarabun นั้น คงเป็นเรื่องน่าเบื่อที่จะต้องมาคอยเปลี่ยน Font ทุกครั้ง

     

    อันที่จริงแล้ว ใน Microsoft Word 2016 (ล่าสุด ณ ตอนเขียนบทความนี้) ท่านสามามารถบันทึกรูปแบบเริ่มต้นทั้งฟอนต์, ขนาดฟอนต์ รวมทั้งรูปแบบตัวอักษรไว้เป็นค่าเริ่มต้นได้เลย (Overwrite the Normal.dotm template) ด้วยวิธีการต่อไปนี้ครัช

     

    1. เลือก Font ที่จะเป็น Font เริ่มต้น ในตัวอย่างเลือกเป็น TH SarabunPSK ขนาด 16 แล้วก็คลิกตามลูกศรชี้

    2. กดที่ Set As Default ตามลูกศรอีกเช่นเคย

    3.เลือก All document based on the Normal.dotm template แล้วกด OK

    เพียงเท่านี้ ค่าที่ตั้งไว้ก็จะเป็นค่าเริ่มต้นทุกครั้งที่เปิด Microsoft Word 2016

    (เนื่องจากผมใช้ UI เป็นภาษาอังกฤษ สำหรับภาษาไทยนั้น ลองเทียบตำแหน่งปุ่มดูนะครับ)

     

    หากมีข้อผิดพลาด ขออภัยไว้ ณ โอกาสนี้ครัช

  • การสร้างเอกสารด้วย Sphinx

    sphinx คือเครื่องมือที่ช่วยในการสร้างเอกสารที่พัฒนาโดย Georg Brandl เดิมที sphinx ได้รับการพัฒนาเพื่อใช้สร้างเอกสารสำหรับ Python แต่สามารถใช้งานกับภาษาอื่นๆได้เช่นกัน

    sphinx ใช้ reStructuredText (ดูข้อมูลเพิ่มเติมเกี่ยวกับ reStructuredText ได้ที่ บทความ ก่อนหน้า) ในการกำหนดรูปแบบของเอกสาร และชุดเครื่องมือในการ parsing และ translating เอกสารในรูปแบบ  reStructuredText ไปเป็นรูปแบบที่ต้องการเช่น html หรือ pdf เป็นต้น

    ในการติดตั้งใช้งาน sphinx นั้นจำเป็นต้องต้องติดตั้ง Python เนื่องจาก sphinx ได้รับการพัฒนาโดยใช้ Python language ทำให้การใช้งาน sphinx ต้องติดตั้ง Python ด้วย โดย Python ที่ใช้ต้องเป็น Python version 2.7 เป็นอย่างน้อย

    การติดตั้ง Python บน windows  ทำได้โดยเข้าไป download “Python windows installer” ที่ https://www.python.org/ และทำการติดตั้ง หลังจากติดตั้งเรียบร้อย จะต้องทำการกำหนดค่า Python executable directory ใน PATH environment variable เพื่อที่จะสามารถ run Python และ package command เช่น sphinx-build ได้จาก command prompt

    Installing Sphinx with pip

    การติดตั้ง Sphinx ทำได้โดยการใช้ “pip”  ซึ่ง pip เป็นเครื่องมือที่ใช้ในการ download และติดตั้ง 3rd-party libraries สำหรับ Python ซึ่งจะถูกรวมอยู่ใน Python official installation ตั้งแต่ version Python-3.4.0

    การติดตั้ง sphinx โดยใช้คำสั่งดังนี้บน command prompt

    C:\> pip install sphinx
    

    หลังจากติดตั้งเรียบร้อย ให้พิมพ์คำสั่ง sphinx-build -h บน command prompt ถ้าทุกอย่างถูกต้อง จะแสดงข้อมูล Sphinx version number และ list ของ option ต่างๆสำหรับคำสั่งนี้

    Setting up the documentation sources

    การพัฒนาเอกสารด้วย sphinx นั้น เริ่มแรกเราจะต้องกำหนดพื้นที่สำหรับพัฒนาเอกสารและจัดเก็บ config ที่ใช้สำหรับ sphinx ซึ่ง sphinx มีคำสั่ง sphinx-quickstart ซึ่งทำหน้าที่กำหนด source directory และสร้าง default config file “conf.py” ที่จำเป็นให้ โดยใช้คำสั่งดังนี้

    C:\> sphinx-quickstart

    sphinx-quickstart script สร้างโครงสร้าง folder พร้อมทั้ง file เริ่มต้นรวมทั้ง Makefile และ make.bat ซึ่งจะใช้ในการ build (parsing และ translating โดยที่ถ้าพบส่วนที่ไม่ตรงตามข้อกำหนด syntax จะแสดง warning หรือ error พร้อมทั้งรายละเอียดของ line เช่นเดียวกับการ build “code program”)

    หลังได้โครงสร้าง folder สำหรับพัฒนาเอกสารเรียบร้อย ก็สามารถเริ่มต้นเขียนเอกสารโดยใช้ reStructuredText ในการกำหนดรูปแบบการแสดงผลของ text จากนั้นเมื่อต้องการสร้างเอกสารในรูปแบบที่ต้องการเช่น html document ก็จะต้องทำการ build โดยใช้คำสั่ง

    C:\> make html

    ผลลัพธ์ที่ได้จากการใช้คำสั่งนี้คือ HTML document ใน folder ที่กำหนด (ใช้คำสั่ง make โดยไม่ระบุ argument เพื่อแสดงประเภทของเอกสารทั้งหมดที่สามารถสร้างได้)

     

    อ้างอิง : http://www.sphinx-doc.org/en/1.5.1/tutorial.html

  • คู่มือเทคนิคการใช้งาน Function พื้นฐานใน Itextsharp สำหรับมือใหม่ ตอนที่ 2

    บทความนี้ผู้เขียนจะพูดถึงส่วนที่มีการทำงานในลักษณะคล้ายกับ Containner แต่ก่อนจะเริ่มเนื้อหาในส่วนนี้ สำหรับผู้ที่เริ่มต้นใหม่สามารถอ่านบทความ ตอนที่ 1 เพื่อความเข้าใจต่อเนื่องกันนะครับ ส่วนผู้ที่อ่านบทความก่อนหน้านี้ เรามาเริ่มกันเลยดีกว่าครับ

    ก่อนที่ผู้เขียนจะไปพูดถึงส่วนของการเขียนโปรแกรมนั้น ผู้เขียนอยากอธิบายเพื่อทำความเข้าใจให้กับผู้อ่านได้เห็นภาพได้ชัดเจนเกี่ยวลักษณะการทำงานของ Containner แบบต่างๆให้ได้ทราบกัน โดยการทำงานของ Itextsharp นั้น เมื่อเราทำการสร้างเอกสารแล้ว เราไม่สามารถเขียนข้อความหรือใส่ข้อมูลต่างๆลงไปได้ในเอกสารโดยตรง แต่เราจะทำผ่านตัว Containner ครับ โดยตัว Containner ที่ Itextsharp ให้มาก็มีหลายรูปแบบให้เลือกใช้งานกัน วันนี้เราจะมาทราบกันว่ามีรูปแบบอะไรบ้างที่ช่วยให้เราทำงานได้ดีขึ้นครับ

    รูปตัวอย่างแสดงการทำงานของ Containner

    จากรูปตัวอย่างที่ผู้เขียนได้วาดไว้นั้น ผู้เขียนขออธิบายกรอบทั้งด้านซ้ายก่อนนะครับ โดยกรอบแต่ละสี จะเป็น Containner แต่ละที่ Itextsharp มีมาให้เราใช้งาน โดยกรอบสีดำนอกสุดนั้น ก็คือ Document หรือตัวเอกสารที่ได้กล่าวถึงในบทความก่อนหน้านี้ ซึ่งเป็น Containner ใหญ่สุดและเป็นตัวหลัก ใช้สำหรับบรรจุ Containner ตัวอื่นๆลงไปในเอกสาร ต่อมากรอบสีน้ำเงิน ก็คือ Paragraph เรียกง่ายๆว่าย่อหน้า ใน 1 Document นั้นเราสามารถบรรจุ Paragraph กี่อันก็ได้ตามที่ผู้ใช้ต้องการ โดยแต่ละ Paragraph จะเรียงต่อกันลงมาเป็นแนวตั้ง โดย Paragraph ล่าสุดจะอยู่ล่าสุดของเอกสารเสมอ ต่อกันด้วยกรอบสีแดง ก็คือ Phrase เรียกง่ายๆว่า รูปประโยค ใน 1 Paragraph สามารถมี Phrase ได้หลายอัน โดยต่อเรียงจากซ้ายไปขวา เราสามารถเขียนข้อมูลลงใน Phraph ได้ หรือเราใช้เป็น Containner สำหรับบรรจุ Chunk อีกชั้นได้ด้วย แต่ Phraph เหมาะสำหรับใช้เป็น containner มากกว่าใช้ใสข้อมูลโดยตรง เนื่องจากมีเงื่อนไขในการใส่ที่จำกัด และสุดท้ายของกรอบด้านซ้ายและเป็นตัวหลักในการเขียนข้อมูลคือ Chunk นั้นเอง Chunk เป็น Containner ที่มีหน้าที่ในการเก็บข้อมูลที่เราจะใส่ลงไปในเอกสารโดยเฉพาะ โดย Chunk จะต่อเรียงกันไปเลยๆจากซ้ายไปขวาเหมือน Phrase และไม่สามารถบรรจุ Containner อื่นลงไปได้อีก พออ่านมาถึงตรงนี้หลายท่านสงสัยว่า เรามาถึง Containner ตัวเล็กสุดแล้ว แล้วอีก 2 ตัวที่เหลือละ จริงๆผู้เขียนไม่ได้ลืมนะครับ แต่ผู้เขียนพยายามแยกการทำงานของ Containner เป็นชุดๆให้ผู้อ่านได้เข้าใจง่ายๆ เมื่อจบการอธิบายในกรอบด้านซ้ายของรูปตัวอย่างแล้ว เรามาเริ่ม กรอบทางด้านขวากันเลยดีกว่า เมื่อเราดูรูปกรอบด้านขวาจะพบว่ามี Containner บ้างตัวหายไป ทั้งที่มีการใช้งานทางด้านซ้าย ก็คือเจ้า Paragraph นั้นเอง เพราะผู้เขียนคิดว่าการทำงานของ Paragraph นั้นจะซ้ำซ้อนกับ PdfPCell นั้นเอง แต่ก่อนจะพูดถึง PdfPCell สิ่งที่ลืมไปไม่ได้เลยคือ PdfPtable นั้นเอง สำหรับผู้พัฒนาโปรแกรม คงเข้าใจได้ง่ายๆว่า ถ้าเราจะสร้างCell เราจะขาด Table ไปไม่ได้ เพราะ Cell เป็นส่วนนึงของ Tableนั้นเอง โดย PdfpTable จะทำหน้าที่ในการบรรจุ Containner PdfPCell ไว้นั้นเอง เมื่อเราทำการใส่ PdfPCell ลงใน PdfPTable แล้ว PdfPCell จะเรียงต่อกันจากซ้ายไปขวา เรื่อยๆ แล้วหลายคนสงสัย แล้วไม่มี PdfPRow ให้ใช้งานหรอ มีครับแต่ไม่ค่อยได้รับความนิยมในการใช้งานมากนัก เพราะตัว PdfPTable นั้นสามารถเพิ่ม PdfPCell ได้โดยตรงไม่ต้องเพิ่ม PdfPRow แต่อย่างใด ผู้เขียนจึงขอตัดออกไปก่อน แต่จะมีตัวอย่างการใช้งานให้ดูตอนท้ายครับ แล้วถามว่าเราสามารถเอา PdfPTable ไปใส่ใน Paragraph ได้ไหม ได้ครับ เราสามารถเอา PdfPTable ใน Paragraph และเช่นเดียวกันเราสามารถเอา Paragraph ใส่ใน PdfPTable รู้สึกผู้เขียนจะร่ายยาวไปแล้ว คนอ่านคงเบื่อ เรามาเข้าสู่ช่วงของการเขียนโปรแกรมกันเลยดีกว่า โดยเริ่มจากตัว Containner ตัวเล็กสุดคือ Chunk

    Chunk chk1 = new Chunk("Howdy",fnt);//1
    
    Chunk chk2 = new Chunk();//2
    chk2.Append("Howdy");
    chk2.Font = fnt;
    
    Phrase P = new Phrase(new Chunk("Howdy", fnt));//3
    

    จากตัวอย่างด้านบนจะเป็นรูปแบบการใช้งาน Chunk ในรูปแบบต่างๆกันขึ้นอยู่กับความเหมาะสมหรือความถนัดของผู้ใช้งาน แบบที่ 1 จะเป็นการประกาศใช้งานพร้อมทั้งกำหนดค่าข้อมูลและรูปแบบของ font ลงไปในขั้นตอนเดียว ส่วนแบบที่ 2 จะแตกต่างตรงที่ประกาศการใช้งาน Chunk ขึ้นมาก่อนแล้วค่อยไปกำหนดค่าข้อมูลและรูปแบบ Font ภายหลัง หรือแบบที่ 3 เป็นการสร้าง Chunk ลงไปใน Containner ตัวอื่นโดยตรง แบบนี้ไม่สามารถแก้ไขข้อมูลได้แล้วครับ Containner ตัวต่อมาคือ Phrase มาดูตัวอย่าง Code กัน

    Chunk ck1 = new Chunk("Howdy ",fnt);
    Chunk ck2 = new Chunk("You",fnt);
    
    Phrase P1 = new Phrase(new Chunk("Howdy You", fnt));//1
    
    Phrase P2 = new Phrase("Howdy You",fnt);//2
    Phrase P3 = new Phrase();//3
    P3.Add("Howdy ");
    P3.Add("You");
    
    Phrase P4 = new Phrase();//4
    P4.Add(ck1);
    P4.Add(ck2);
    
    Paragraph PR1 = new Paragraph(new Phrase("Howdy You",fnt));//5
    

    จากตัวอย่างทั้งหมด ผลลัพธ์ที่ได้คือ Howdy You เหมือนกันหมดครับต่างกันแค่วิธีการเขียนเท่านั้นเอง ในตัวอย่างที่ 1 เป็นการใช้งานแบบประกาศ Phrase ขึ้นมาพร้อมกับสร้าง Chunk ขึ้นมาพร้อมกำหนดค่าข้อมูลเพิ่มมาด้วยในชุดคำสั่งเดียว ซึ่งในตัวอย่างที่ 2 มีการเขียนเหมือนกันต่างตรงที่ เขียนข้อมูลและรูปแบบตรงๆ ไม่ผ่านทาง Chunk นั้นเอง ส่วนตัวอย่างที่ 3 และ 4 จะมีการประกาศใช้งาน Phrase ในชื่อ P3 และ P4 ต่างกันตรงที่ P3 จะทำการเพิ่มข้อมูลตรงในรูปแบบของ String แต่ P4 จะนำ Chunk ที่ได้สร้างไว้ก่อนมาใช้งาน ถ้าสังเกตุดีๆจะพบว่า แบบตัวอย่างที่ 3 นั้นไม่สามารถกำหนดรูปแบบของข้อความได้ ต่างจากตัวอย่างที่ 4 ที่มีการกำหนดรูปแบบมาแล้วใน Chunk ซึ่งแบบนี้จะทำงานได้ง่ายกว่าและยืดหยุ่นมากว่าด้วยครับ และสุดท้ายตัวอย่างที่ 5 เป็นการสร้าง Phrase ซ้อนอยู่ในการประกาศ Paragarph นั้นเอง ทำให้เราไม่สามารถแก้ไขข้อมูลใน Phraseได้แล้วครับ Containner ตัวต่อมาที่จะพูดถึงคือ Paragarph มาดูตัวอย่าง Code กัน

    Paragraph PR1 = new Paragraph(new Phrase("Howdy You",fnt));//1
    
    Paragraph PR2 = new Paragraph(new Phrase(new Chunk("Howdy You", fnt)));//2
    
    Paragraph PR3 = new Paragraph();//3
    PR3.Add("Howdy You");
    
    Paragraph PR4 = new Paragraph();//4
    PR4.Add(new Chunk("Howdy You", fnt));
    
    Paragraph PR5 = new Paragraph();//5
    PR5.Add(new Phrase(new Chunk("Howdy You", fnt)));
    
    Paragraph PR6 = new Paragraph();//6
    PR6.Add(P1);
    
    Paragraph PR7 = new Paragraph();//7
    PR7.Add(ck1);
    PR7.Add(ck2);
    
    pdfDoc.Add(new Paragraph("Howdy You"));//8
    

    จากตัวอย่างรูปแบบที่ 1 และ 2 เป็นการเขียนในลักษณะที่คล้ายกันคือทำการประกาศ Paragraph พร้อมทั้งประกาศ Containner ตัวที่เล็กกว่าใส่ลงไปด้วยและทำการเขียนข้อมูล ต่างกันเพียง แบบที่ 2 จะประกาศซ้อนลงไปอีกชั้นนึงในส่วนของ Chunk นั้นเอง ส่วนตัวอย่างแบบที่ 4 5 6 และ 7 ใช้การประกาศ Containner ที่เหมือนกัน ต่างกันตรงการเพิ่มข้อมูลลง Paragraph นั้นๆ และสุดท้ายตัวอย่างที่ 8 คือการประกาศ Paragraph ลงไปใน Document เลยนั้นเอง แล้วเราก็มาถึง 2 ตัวสุดท้ายของบทความนี้แล้วครับ นั้นก็คือ PdfPtable และ PdfPcell นั้นเอง นั้นส่วนของ 2 ตัวนี้จะยกตัวอย่างแบบพื้นฐานให้ดูก่อนนะครับ จะไม่ได้ดูรายละเอียดเยอะมาก เดี๋ยวจะยาวเกินไปครับ เรามาดูตัวอย่างกันเลยดีกว่า

    //-------------- 1 -------------//
    PdfPTable PdfTable = new PdfPTable(4);
    float[] tbwidths = { 10f, 10f, 10f, 10f };
    PdfTable.SetWidths(tbwidths);
    
    //-------------- 2 -------------//
    PdfPCell PdfCell = new PdfPCell(new Phrase("Howdy You",fnt));
    PdfPCell PdfCell2 = new PdfPCell(new Phrase(new Chunk("Howdy You", fnt)));
    PdfPCell PdfCell3 = new PdfPCell();
    PdfCell3.AddElement(P1);
    
    //-------------- 3 -------------//
    PdfTable.AddCell(PdfCell);
    PdfTable.AddCell(PdfCell2);
    PdfTable.AddCell(PdfCell3);
    PdfTable.AddCell(new PdfPCell(new Phrase("Howdy You",fnt)));
    

    จากตัวอย่างผู้เขียนได้แบ่งcode ออกเป็น 3 ส่วนดังนี้ ส่วนที่ 1 จะเป็นส่วนของการประกาศและสร้าง Table ขึ้นมาครับ โดยผู้เขียนได้สร้าง Table ชื่อ PdfTable ซึ่ง Table นี้มีขนาด 4 Colunm บบรทัดต่อมาจะเป็นส่วนของการจัดความกว้างของ Colunm ส่วนนี้ต้องระวังนิดนึงคือ จำนวนต้องมีเท่ากับจำนวน Colunm ของ Table นะครับ ส่วนเรื่องขนาดความกว้าง อันนี้แล้วแต่ตามความเหมาะสมในการใช้งาน ตัวโปรแกรม Itextsharp ช่วยเราเรื่องการขยายขนาดให้พอดีครับ อันนี้ต้องลองเล่นๆดูจะเข้าใจมากขึ้น บรรทัดต่อมาเป็นการนำค่าความกว้างที่ตั้งไว้กำหนดให้ Table ของเรา ก็จะจบการสร้างtableแบบพื้นฐานแล้ว เรามาต่อกันส่วนที่ 2 ในส่วนนี้จะเป็นส่วนของการประกาศและสร้าง PdfPCell ในรูปแบบต่างๆ ซึ่งรูปแบบจะคล้ายๆกับการสร้าง containner ตัวอื่นๆที่ผ่านมา และส่วนที่ 3 เป็นส่วนที่นำเอาส่วนที่ 2 หรือก็คือ PdfPCell ของเรานั้นเอง ใส่ลงไปยัง PdfPTable ที่ได้สร้างไว้ในส่วนที่ 1 แค่นี้ก็ถือว่าเสร็จสิ้นการสร้าง Table แล้วครับ แล้วลืมไม่ได้เลยคือตัวอย่างการใช้งาน PdfPRow ที่ได้สัญญาเอาไว้ในตอนแรก

    //-------------- 1 -------------//
    PdfPTable PdfTable = new PdfPTable(4);
    float[] tbwidths = { 10f, 10f, 10f, 10f };
    PdfTable.SetWidths(tbwidths);
    
    //-------------- 2 -------------//
    PdfPCell PdfCell = new PdfPCell(new Phrase("Howdy You",fnt));
    PdfPCell[] cells = new PdfPCell[] { new PdfPCell(), new PdfPCell(), new PdfPCell(), new PdfPCell()};
    
    cells[0].AddElement(new Phrase("Howdy You", fnt));
    cells[1].AddElement(new Phrase(new Chunk("Howdy You", fnt)));
    cells[2].AddElement(PR1);
    cells[3] = PdfCell;
    
    //-------------- 3 -------------//
    PdfPRow row = new PdfPRow(cells);
    PdfTable.Rows.Add(row);
    

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

  • มัลแวร์สวมรอยการใช้งาน Facebook

    มีรายงานจากศูนย์ประสานการรักษาความมั่นคงปลอดภัยระบบคอมพิวเตอร์ประเทศไทย (ไทยเซิร์ต) เมื่อวันที่ 10 พ.ค. 2559 พบว่ามีการแพร่กระจายมัลแวร์ประเภท Malicious Code ผ่าน Facebook โดยอาศัยช่องทางการแจ้งเตือนของ Facebook

    การทำงานของมัลแวร์

    เมื่อผู้ใช้ได้รับการแจ้งเตือนจาก Facebook ว่าถูกพาดพิงโดยบุคคลที่สาม หากผู้ใช้คลิกเข้าไปดูข้อความแจ้งเตือนดังกล่าวก็จะถูกนำไปยังไซต์อื่นทันที และเว็บไซต์ปลายทางที่ถูกนำพาไปจะปรากฏข้อความว่าเป็นส่วนขยายของ Browser สำหรับใช้เปลี่ยนสีของเว็บไซต์ Facebook และให้ดาวน์โหลดไฟล์ Instalador_Cores.scr มาติดตั้ง ซึ่งเป็นส่วนขยายของ Google Chrome

    รูปที่ 1 หน้าเว็บไซต์ปลายทางมีให้ดาวน์โหลดไฟล์ Instalador_Cores.scr

    หากผู้ใช้หลงเชื่อดาวน์โหลดและติดตั้งจะพบว่ามีการสร้างไฟล์ไว้ที่ไดเรกทอรี่ C:\User\[ชื่อผู้ใช้]\AppData\Local\Google\Update จากนั้นจะสร้าง Shortcut สำหรับเรียกใช้งาน Google Chrome ไว้ที่ Desktop โดยตัว Shortcut ดังกล่าวจะเป็นการเปิดใช้งาน Google Chrome โดยโหลดส่วนเสริมที่ถูกติดตั้งใหม่ขึ้นมาทำงานด้วย

    หากเปิดใช้งาน Google Chrome จาก Shortcut ดังกล่าว และเข้าใช้งานเว็บไซต์ Facebook ก็จะพบว่าสีของ Facebook เปลี่ยนเป็นสีเขียวดังรูปที่ 2 และยังสามารถปรับแต่งเป็นสีอื่นได้ตามต้องการ

    รูปที่ 2 ตัวอย่างส่วนขยายของ Google Chrome ที่สามารถเปลี่ยนสีเว็บไซต์ Facebook ได้

    นอกจากการทำงานดังกล่าวแล้วมัลแวร์ตัวนี้ยังได้แฝงการทำงานเบื้องหลังไว้โดยจะตรวจสอบว่ามีการล็อคอิน Facebook ไว้หรือไม่ หากใช่ก็จะสวมรอยไปโพสต์คอมเมนต์ในเว็บไซต์ pinandwin8.co.nz ทันที โดยในคอมเมนต์ก็จะมีการอ้างถึงผู้อื่นที่อยู่ในรายชื่อเพื่อนของผู้ใช้อีกด้วย

    การแก้ไขหากตกเป็นเหยื่อ

    1. ไปที่ไดเรกทอรี C:\User\[ชื่อผู้ใช้]\AppData\Local\Google\Update แล้วลบไดเรกทอรี่และไฟล์ที่มัลแวร์สร้าง ดังนี้ ไดเรกทอรี่ css, img, js ไฟล์ manifest.json, popup.html และ background.html
    2. ลบไอคอน Google Chrome ที่ถูกสร้างขึ้นใหม่ออกจาก Desktop

    การป้องกันการโจมตี

    1. ผู้ใช้ Facebook ควรอ่านข้อความแจ้งเตือนที่ปรากฏบนหน้าจอ โดยเฉพาะเมื่อ Facebook แจ้งว่าการคลิกลิงก์จะเป็นการเปลี่ยนเส้นทางไปยังเว็บไซต์อื่น
    2. หากคลิกลิงก์จาก Facebook แล้วพบหน้าจอขอให้ใส่รหัสผ่าน ไม่ควรใส่ข้อมูลเพราะอาจเป็นหน้าเว็บไซต์หลอกลวง (Phishing)
    3. หากคลิกลิงก์จาก Facebook แล้วพบหน้าจอขอให้ดาวน์โหลดโปรแกรม ควรพิจารณาก่อนดาวน์โหลดโปรแกรมนั้นเพราะอาจเป็นอันตรายได้
    4. ผู้ดูแลระบบอาจพิจารณาบล็อคเว็บไซต์ pinandwinco.nz เนื่องจากเป็นเว็บไซต์ที่เผยแพร่มัลแวร์

    แหล่งข้อมูลอ้างอิง

  • มัลแวร์เรียกค่าไถ่ Ransomware

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

    รูปที่ 1 ตัวอย่างหนังสือราชการแจ้งเตือนให้เพิ่มความระมัดระวังในการเปิดอ่านจดหมายอิเล็กทรอนิกส์
    [ที่มา : http://www.tourism.go.th/subweb/details/7/88/24949 และ http://www.chkr.go.th/2/images/vs.pdf ]
    มัลแวร์ที่ประสงค์ร้ายต่อข้อมูลในอุปกรณ์ต่าง ๆ ของเราดังกล่าว จัดเป็นมัลแวร์ประเภท “Ransomware” หรือ “มัลแวร์เรียกค่าไถ่” มีเป้าหมายที่ตรวจพบการโจมตีแล้วทั้งในระบบปฏิบัติการ Window, Android, iOS และ Linux โดยแบ่งตามการทำงานออกเป็น 2 รูปแบบหลัก ๆ อุปกรณ์ต่าง ๆ ของเรานคือ

    1. Lock Screen Ransomware
      Ransomware รูปแบบนี้จะใช้ความสามารถของ Lock Screen ทำการล็อคหน้าจอหรือปิดกั้นการเข้าใช้งานเครื่องคอมพิวเตอร์ หรือสมาร์ทโฟนของเหยื่อไว้ ไม่ให้สามารถเข้าถึงโปรแกรมต่าง ๆ และข้อมูลในเครื่องได้ พร้อมทั้งแสดงข้อความเรียกค่าไถ่เพื่อปลดล็อคดังรูปที่ 2 เป็นหน้าจอของสมาร์ทโฟนระบบปฏิบัติการ Android ที่ติด Ransomware ชื่อ iToper
      รูปที่ 2 ตัวอย่างหน้าจอสมาร์ทโฟนที่ติดมัลแวร์ชนิด Lock Screen Ransomware ที่ชื่อ iToper
      [ที่มา : http://www.cmcm.com/blog/en/security/2015-06-16/645.html ]
    2. File Encrypting Ransomware
      เครื่องผู้ใช้งานที่ติด Ransomware ในรูปแบบนี้จะสามารถใช้งานอุปกรณ์ และเข้าถึงโปรแกรมต่าง ๆ ได้ตามปกติ แต่ไฟล์ต่าง ๆ ที่อยู่ในเครื่องทั้งหมด ไม่ว่าจะเป็นไฟล์เอกสาร ไฟล์วีดีโอ หรือไฟล์รูปภาพ และอื่น ๆ จะถูกเข้ารหัสไว้ไม่ให้ผู้ใช้งานสามารถเข้าถึงได้ จากนั้นจึงเรียกค่าไถ่โดยการทิ้งข้อความแสดงคำแนะนำวิธีการจ่ายเงินเพื่อแลกกับคีย์ที่ใช้ในการถอดรหัสไฟล์กลับคืนมาดังรูปที่ 3 เป็นตัวอย่างหน้าจอการเรียกค่าไถ่ของ Ransomware รูปแบบนี้ที่ชื่อ CryptoLocker
      รูปที่ 3 หน้าจอของเครื่องคอมพิวเตอร์ที่ติด Ransomware รูปแบบ File Encrypting ransomware ชื่อ CryptoLocker
      [ที่มา : https://www.thaicert.or.th/papers/technical/2013/pa2013te011.html ]

      สถิติการโจมตีของ Ransomware

      มีสถิติที่น่าสนใจจาก Solutionary ซึ่งเป็นบริษัทด้านความปลอดภัยในเครือ NTT Group ได้ออกรายงานสถิติการโจมตีของ Ransomware ที่ตรวจพบได้ในไตรมาสที่ 2 ของปี 2016 พบว่าหน่วยงานด้านสาธารณสุขเป็นหน่วยงานที่ถูกโจมตีมากที่สุดถึง 88% รองลงมาคือหน่วยงานด้านการศึกษา 6% และหน่วยงานด้านการเงิน 4% โดย Ransomware สายพันธ์ที่ตรวจพบมากที่สุดคือ CryptoWall คิดเป็น 94%

    รูปที่ 4 สถิติการโจมตีของ Ransomware ในไตรมาสที่ 2 ปี 2016 [ที่มา : https://www.helpnetsecurity.com/2016/07/27/ransomware-healthcare-industry ]

    ช่องทางการโจมตีของ Ransomware

    1. การโจมตีส่วนใหญ่จะมาทางอีเมล์หลอกลวงที่แนบไฟล์ Ransomware ไว้ โดยเนื้อหาในอีเมล์จะดึงดูดให้ผู้อ่านอยากคลิกเข้าไปอ่าน เช่น อีเมล์แจ้งเลขที่ใบสั่งซื้อสินค้า (OrderID) หากผู้ใช้ไม่คลิกไปเปิดไฟล์แนบ ก็อาจจะทำให้สูญเสียโอกาสทางการค้าได้ ซึ่งถ้าผู้ใช้คลิกเปิดไฟล์โดยไม่ระมัดระวัง ก็จะตกเป็นเหยื่อของ Ransomware ทันที ไฟล์แนบที่มากับอีเมล์จะเป็น zip file หากแตกไฟล์ออกมาก็จะพบไฟล์นามสกุล .doc, .xls, .ppt หรือไฟล์อื่นๆ ที่เราคุ้นเคย แต่ถ้าสังเกตดี ๆ จะพบว่านามสกุลของไฟล์จริง ๆ แล้วเป็น .exe เรียกเทคนิคการตั้งชื่อไฟล์แบบนี้ว่า Double Extensions
    2. โจมตีด้วยวิธี Social Engineering เป็นการหลอกผู้ใช้งานให้ดาวน์โหลดโปรแกรมมาติดตั้งในเครื่อง เช่น ในขณะที่ใช้งานระบบลงทะเบียนเรียนออนไลน์ของมหาวิทยาลัย พบว่ามี Pop-up ขึ้นมาบอกว่า ให้ดาวน์โหลดโปรแกรมเสริมมาติดตั้งเพื่อให้สามารถลงทะเบียนได้สะดวก และรวดเร็วขึ้น ทั้ง ๆ ที่โปรแกรมนี้ไม่มีอยู่จริง หากผู้ใช้งานหลงเชื่อและทำการดาวน์โหลดมาติดตั้ง ไฟล์ต่าง ๆ ก็จะโดนจับเป็นตัวประกันทันที
    3. โจมตีทางช่องโหว่ของ Browser รวมถึง Add-on, Plug-in ต่าง ๆ เช่น Java, Flash และ Acrobat Reader เป็นต้น

    เทคนิคที่ File Encrypting Ransomware ใช้ในการเข้ารหัส

    Ransomware ส่วนใหญ่จะเข้ารหัสไฟล์โดยใช้ Asymmetric Key Algorithms ประกอบด้วยกุญแจ 2 ดอก คือ Public Key ใช้ในการเข้ารหัส และ Private Key ใช้ในการถอดรหัสดังรูป

    รูปที่ 5 การเข้ารหัส และถอดรหัส [ที่มา : https://www.hotforsecurity.com /blog /how-does-ransomware-work-the-ultimate-guide-to-understanding-ransomware-part-ii-11856.html]

    ขั้นตอนการทำงานของ Ransomware

    การโจมตีของ Ransomware จะมีขั้นตอนการทำงาน 6 ขั้นตอน ดังรูป โดย 3 ขั้นตอนสุดท้ายจะใช้การสื่อสารผ่าน TOR (The Onion Router) เพื่อปกปิดตัวตนของโจร และทำให้ไม่สามารถทราบได้ว่าเชื่อมต่อจากที่ไหน

    รูปที่ 6 ขั้นตอนการทำงานของ File Encrypting Ransomware [ที่มา : https://www.sans.org/reading-room/whitepapers/incident/enterprise-survival-guide-ransomware-attacks-36962]
    1. ส่งข้อมูลหลอกลวงผู้ใช้งานในรูปแบบของอีเมล์ที่มีไฟล์แนบ หรือลิงค์สำหรับดาวน์โหลดโปรแกรม
    2. ผู้ใช้งานดาวน์โหลดไฟล์ Ransomware จากไฟล์แนบหรือลิงค์หลอกลวง
    3. ผู้ใช้งาน Double Click เพื่อเปิดไฟล์ที่ดาวน์โหลดมา ก็จะเป็นการสั่งให้ Ransomware ทำงานทันที
    4. Ransomware ทำการเชื่อมต่อไปยัง Command and Control Center (C&C) หรือเครื่องเซิร์ฟเวอร์ที่ทำหน้าที่เก็บข้อมูล และคีย์ที่ใช้ในการถอดรหัสของเหยื่อแต่ละราย ซึ่ง Ransomware จะต้องทำการเชื่อมต่อ C&C ให้ได้ก่อนที่จะดำเนินการขั้นต่อไป จากนั้นจึงสร้าง RSA Key ขนาด 2,048 bits ขึ้นมาคือ Public Key ที่ใช้สำหรับเข้ารหัส และ Private Key ที่ใช้สำหรับถอดรหัสโดย C&C จะเก็บ Private Key ไว้ และส่ง Public Key ไปยังเครื่องเหยื่อ
    5. Ransomware จะทำการค้นหาไฟล์ต่าง ๆ บนเครื่องเหยื่อโดยดูจากนามสกุลไฟล์ ทั้งไฟล์รูปภาพ (เช่น .jpg, .gif, .png) วีดีโอ (เช่น .avi, .mpeg, .mov) และเอกสาร (เช่น .doc, docx, xls, xlsx) เป็นต้น จากนั้นจึงใช้ RSA Algorithm เข้ารหัสไฟล์ด้วย Public Key และแสดงตัวเพื่อเรียกค่าไถ่โดยการทิ้งข้อความแจ้งเตือนเหยื่อว่าไฟล์ทั้งหมดถูกเข้ารหัสแล้ว ไม่สามารถใช้งานได้ และเหยื่อต้องยอมจ่ายเงินเป็นจำนวนที่โจรต้องการในรูปแบบของ Bitcoins เพื่อแลกกับ Private Key ที่ใช้ในการถอดรหัสภายในระยะเวลาที่กำหนด ไม่เช่นนั้นจะขึ้นค่าไถ่ หรือทำลายคีย์ทิ้ง และจะไม่สามารถถอดรหัสไฟล์ได้อีก
    6. หากเหยื่อจ่ายเงินค่าไถ่ตามคำแนะนำของโจร ก็อาจจะได้รับ Private Key ภายใน 2 – 48 ชั่วโมง และจะทำการถอดรหัสไฟล์ให้โดยอัตโนมัติ แต่ไม่รับประกันว่าจะสามารถถอดรหัสได้ทุกไฟล์หรือไม่

    จากข้อมูลผู้ให้บริการตรวจสอบชนิดของ Ransomware ที่ https://id-ransomware.malwarehunterteam.com สามารถตรวจสอบและระบุตัว ransomware ได้ต่างกัน 187 ชนิด ซึ่งแต่ละชนิดจะมีรายละเอียดต่างกัน เช่น CryptoLocker และ Ransom32 มีรายละเอียดดังนี้

    CryptoLocker

    เป็นมัลแวร์ที่แพร่กระจายในรูปของไฟล์แนบ zip file ในอีเมล์ซึ่งถูกส่งมาจากผู้ส่งที่น่าเชื่อถือ หากแตกไฟล์ออกมาก็จะพบไฟล์ .exe ในรูปของไฟล์เอกสาร เช่น pdf, word, excel เป็นต้น หากผู้ใช้ Double Click จะทำให้ไฟล์ต่าง ๆ ถูกเข้ารหัสทันที โดยตัวอย่างหน้าจอ CryptoLocker เป็นดังรูป

    รูปที่ 7 หน้าจอคอมพิวเตอร์ที่โดน CryptoLocker เข้ารหัสไฟล์เรียบร้อยแล้ว และรายชื่อไฟล์ที่ถูกเข้ารหัส [ที่มา : https://www.it24hrs.com/2015/ransomware-alert]

    Ransom32

    เป็นมัลแวร์รูปแบบใหม่ที่พัฒนาโดยใช้ภาษา Java Script ภายใต้แนวคิด Software as a Service (SaaS) เชื่อมต่อกับ C&C ผ่านทาง TOR เช่นเดียวกับ Ransomware สายพันธ์อื่น ๆ  การพัฒนาด้วยแนวคิด SaaS จะทำให้ใครก็ตามสามารถสร้างมัลแวร์เป็นของตนเองได้ทันทีโดยอาศัยการตั้งค่าต่าง ๆ เช่น จำนวนเงินที่เรียกร้อง และข้อความแจ้งเตือน เป็นต้น ผ่านทางเว็บไซต์ที่ซ่อนอยู่ภายในเครือข่าย TOR

    รูปที่ 8 ตัวอย่างข้อความเรียกค่าไถ่ของ Ransom32
    [ที่มา : http://securityaffairs.co/wordpress/43250/cyber-crime/ransom32-crypto-ransomware.html]

    หากตกเป็นเหยื่อของ Ransomware แล้วต้องทำอย่างไร

    1. ในกรณีที่ไฟล์ที่ถูกเข้ารหัสเป็นไฟล์สำคัญจริง ๆ ก็ต้องจ่ายเงิน แต่ก็ไม่สามารถรับประกันได้ว่าจะสามารถได้ไฟล์คืนมา เนื่องจากการทำธุรกรรมกับโจรย่อมมีความเสี่ยงที่จะเป็นผู้เสียเงินฝ่ายเดียว หากเป็นไปได้ไม่ควรใช้วิธีการนี้ เนื่องจากการจ่ายเงินเป็นการสนับสนุนธุรกิจของโจร
    2. ห้ามใช้เครื่องที่ติด Ransomware เชื่อมต่อกับเครือข่าย Flash Drive หรือ External Hardisk เนื่องจากอาจจะเป็นการกระจายมัลแวร์ไปยังเครื่องอื่น ๆ ได้
    3. ควร Format เครื่อง และติดตั้งระบบปฏิบัติการใหม่

    การป้องกันภัยจาก Ransomware

    • เนื่องจากช่องทางการแพร่กระจายของ Ransomware โดยส่วนใหญ่จะมาทางอีเมล์ขยะ ผู้ใช้งานจึงควรเลือกใช้โปรแกรมสำหรับจัดการอีเมล์ และบริการอีเมล์ที่มีคุณสมบัติการช่วยกรองอีเมล์ขยะที่มีประสิทธิภาพ
    • ควรเพิ่มความระมัดระวังในการใช้อินเตอร์เน็ตให้มากยิ่งขึ้น หากสงสัยว่าไฟล์ที่ดาวน์โหลดมาเป็นมัลแวร์ ก็สามารถทำการตรวจสอบได้โดยการอัพโหลดไฟล์ดังกล่าวไปทดสอบกับเว็บไซต์ https://www.virustotal.com
    • ตั้งค่าเครื่องคอมพิวเตอร์ให้แสดงนามสกุลไฟล์ จะทำให้สังเกตไฟล์ที่มีลักษณะเป็น Double Extension ซึ่งเป็นเทคนิคที่ Ransomware ใช้ในการหลอกลวงผู้ใช้ได้ง่ายยิ่งขึ้น
    • ทำการอัพเดทโปรแกรมต่าง ๆ ที่มักจะเป็นเป้าหมายในการฝังมัลแวร์ไว้ เช่น Java, Adobe Flash Player, Microsoft Silverlight, Adobe Reader, Web Browser เป็นต้น รวมทั้งระบปฏิบัติการ และโปรแกรม Antivirus ให้ทันสมัยอยู่เสมอ
    • สำรองข้อมูลอย่างสม่ำเสมอไว้ในฮาร์ดดิสสำรองเพื่อป้องกันข้อมูลสูญหาย ซึ่งเมื่อทำการสำรองข้อมูลเสร็จแล้วควรรีบปลดสายออก
    • ควรติดตั้งส่วนเสริมสำหรับ Browser ที่ใช้ในการปิดกั้นโฆษณา เนื่องจากมัลแวร์มีการแพร่กระจายโดยการฝัง Script สำหรับดาวน์โหลดมัลแวร์ไว้ในแบนเนอร์โฆษณา

    แหล่งที่มาของข้อมูล

    • https://www.sans.org/reading-room/whitepapers/incident/enterprise-survival-guide-ransomware-attacks-36962
    • https://izonex.wordpress.com/2008/10/26/anoymous-software-tor
    • https://www.it24hrs.com/2015/ransomware/
    • https://www.hotforsecurity.com/blog/money-or-data-the-ultimate-guide-to-understanding-ransomware-part-i-11808.html
    • https://www.techtalkthai.com/ransom32-saas-ransomware/
    • http://securityaffairs.co/wordpress/43250/cyber-crime/ransom32-crypto-ransomware.html
    • http://www.aripfan.com/ransomware-email-virus/
    • https://www.helpnetsecurity.com/2016/07/27/ransomware-healthcare-industry
    • http://www.tourism.go.th/subweb/details/7/88/24949

     

  • คู่มือเทคนิคการใช้งาน Function พื้นฐานใน Itextsharp สำหรับมือใหม่ ตอนที่ 1

    หลังจากที่ผู้เขียนได้ทดลองใช้งาน Itextsharp มาเป็นระยะเวลานึง ในระหว่างที่ได้ทำการใช้งานนั้น ก็เกิดปัญหาต่างๆจากการใช้งานมากมาย ซึงมาจากความไม่รู้ของผู้เขียนเอง เลยได้ทำการรวบรวมข้อมูลวิธีใช้งานเบื้องต้น ให้กับผู้ที่สนใจใช้งาน Itextshap ได้สะดวกมากขึ้น ซึ่งจริงๆแล้วมีพี่ท่านนึงได้เขียนบทความเกี่ยวกับเรื่องนี้ไว้แล้วบ้างส่วน สำหรับผู้ที่สนใจสามารถอ่านได้จาก Link นี้ครับ สร้างเอกสาร PDF ด้วย iTextSharp ส่วนในบทความนี้จะทำการขยายรายละเอียดลงไปในแต่ละ Function ครับ โดย Function ที่จะพูดถึงในบทความนี้มีดังต่อไปนี้

    1. BaseFont และ Font คืออะไร

    ถ้าจะให้พูดถึง Function Basefont ให้เข้าใจง่ายๆแล้วละก็ หน้าที่ของมันคือเป็นการประกาศให้ตัว Itextsharp ทราบว่าเราต้องการใช้ Font อะไรในการทำงานบ้าง สามารถเทียบได้กับช่องเลือก Font ในโปรแกรม Office นั้นแหละครับ และ Function Font จะสร้างรูปแบบของ Font ได้ตามที่เราต้องการ ไม่ว่าจะเป็น ตัวหนา เอียง ขีดเส้นใต้ ขีดเส้นทับ เป็นค่าเริ่มต้นไว้ แล้วหลังจากนั้นเราก็สามารถนำไปใช้งานได้ตลอดการสร้างเอกสาร โดยอ้างอิง Font ที่ใช้งานมาจาก BaseFont อีกทีนึง

    ตอนนี้ก็มาดูรูปแบบการสร้าง BaseFont และทำ Font ต้นแบบเป็นตัวหนานะครับโดยสามารถทำได้ 2 วิธีคือ

    • กรณีที่เรามีชุดของ Font มาแล้วนะครับ(คือแยกตัวหนา ตัวเอียง ขีดเส้น)
    BaseFont bf_bold = BaseFont.CreateFont(@"C:\WINDOWS\Fonts\THSarabunNewBold.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED, true);
    
    Font fnt = new Font(bf, 12);
    
    
    • กรณีที่เรามี Font แค่รูปแบบเดียว
    BaseFont bf = BaseFont.CreateFont(@"C:\WINDOWS\Fonts\THSarabun.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED, true);
    
    Font fnt = new Font(bf, 12,Font.BOLD);

    จากตัวอย่างทั้ง 2 แบบ เราจะมี Font ที่มีรูปแบบของตัวหนาในชื่อของตัวแปร fnt ไว้ใช้งานได้เหมือนกันครับ โดยจะมีความแตกต่างกันคือ แบบที่ 1 นั้น จะเป็นการนำเอารูปแบบของ Font ที่ได้อ้างอิงเอาไว้มาแสดงผลบนเอกสารโดยตรง ต่างจากแบบที่ 2 จะเป็นการนำเอา Font ที่ได้ประกาศเอาไว้แบบตัวอักษรปกติมาแปลงผ่านตัว Itextsharp ให้กลายเป็นตัวหนา อีกทีโดยผ่านทาง property Font.BOLD ครับ แล้วหลายๆท่านคงสงสัยว่าทั้ง 2 แบบมีข้อดีข้อเสียอย่างไร ในแบบที่ 1 การแสดงผลของ font จะถูกต้อง สวยงามตามต้นฉบับ font ที่เราได้ทำการอ้างอิงไว้ครับ แต่ข้อเสียคือ ถ้าเราต้องการสร้าง Font ต้นแบบไว้ในหลายลักษณะ เราก็ต้องอ้างอิงตัวรูปแบบ Font ที่เราต้องการทั้งหมดไปด้วย ส่วนแบบที่ 2 นั้น เราสามารถใช้ Font อ้างอิงเพียงอันเดียว แล้วสร้างรูปแบบ Font ตามที่เราต้องการได้ไม่จำกัด แต่การแสดงผลอาจไม่สวยงามเท่ากับแบบที่ 1

    แล้วถ้าเราต้องการที่จะใส่สีให้กับ font ของเราละ จะสามารถทำได้หรือไม่ คำตอบคือ ทำได้ครับ โดยใน Function Font นั้น ถูกออกแบบมาให้เราสามารถทำรูปแบบของ font ได้หลากหลายรูปแบบครับ มาดูตัวอย่างกัน

    BaseFont bf = BaseFont.CreateFont(@"C:\WINDOWS\Fonts\THSarabun.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED, true);
    Font fnt = new Font(bf, 12,Font.BOLD,BaseColor.red);
    Font fnt = new Font(bf, 16,Font.Italic,BaseColor.green);
    Font fnt = new Font(bf, 12,Font.BOLD | Font.Italic);
    Font fnt = new Font(bf, 12 Font.BOLD | Font.Underline, BaseColor.blue)

    จากตัวอย่างที่ยกให้ดูในข้างต้นนั้น เมื่อนำไปใช้จะได้ผลลัพท์ดังต่อไปนี้

    ตัวอย่างที่ 1  AAA

    ตัวอย่างที่ 2  AAA

    ตัวอย่างที่ 3  AAA

    ตัวอย่างที่ 4  AAA

    จากตัวอย่างทั้ง 4 แบบนั้น ผมได้นำวิธีการทำแบบที่ 2 มาใช้คือการอ้างอิง font จากรูปแบบเดียว แล้วมาแปลงรูปแบบจาก Function Font อีกรอบ ตามที่เราต้องการครับ ดูแล้วไม่ยากเลยใช่ไหมครับ

    ตอนนี้ก็มาถึงข้อสรุปการใช้งาน Function BaseFont และ Font คือ

    • สร้าง Basefont ขึ้นมาโดยอ้างอิงไปยัง Font หรือ ชุดรูปแบบ Font ที่เราต้องการใช้งาน
    • สร้าง Font ตามรูปแบบที่เราต้องการ โดยอ้างอิงจาก Basefont
    • รูปแบบที่สามารถกำหนดได้มี ขนาดของFont รูปแบบของ Font(สามารถผสมได้) และสีของ Font

    2. Function สำหรับสร้างเอกสารและ export ออกไปเป็น PDF

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

    Document pdfDoc = new Document(PageSize.A4, 30, 30, 20, 20);

    จากตัวอย่าง จะเห็นว่าเราทำการสร้างเอกสารขึ้นมาโดยใช้ชื่อว่า pdfDoc เป็นเอกสารขนาด A4 โดยมีการกั้นขอบกระดาษไว้ ด้านซ้าย 30 ด้านบน 30 ด้านขวา 20 และด้านล่าง 20  แล้วค่าตัวเลขนี้มาจากไหน เราจะรู้ได้ยังไงว่าโปรแกรมจะเว้นที่ว่างบนกระดาษเท่าไร ผมมีคำตอบครับ จากการค้นหามามีการกำหนดเป็นมาตรฐานของกระดาษ โดยสามารถอ้างอิงได้ตามนี้ครับ 1 in = 2.54 cm = 72 points. ซึงตัวเลข 30,30,20,20 ก็คือค่า point นั้นเอง จากตัวอย่าง 30 point เท่ากับ 0.4 นิ้ว หรือประมาณ 1 เซนติเมตรนั้นเอง แล้วถ้าเราต้องการเปลี่ยนขนาดกระดาษละ จะต้องทำอย่างไร เราสามารถเปลี่ยนขนาดของกระดาษได้จาก Property PageSize นั้นเอง ซึ่งมีรูปแบบกระดาษให้เลือกมากมายไม่ว่าจะ ซองจดหมาย A4 A3 A2 เป็นต้น ซึ่งการเลือกขนาดของกระดาษก็ขึ้นอยู่กับลักษณะงานที่เราต้องการจะแสดงว่าต้องการขนาดเท่าไร แล้วเราสามารถตั้งค่ากระดาษเป็นแนวตั้งหรือแนวนอนได้ไหม สามารถทำได้เช่นกันครับ ตามตัวอย่างนี้เลย

    Document pdfDoc = new Document(PageSize.A4.Rotate(), 20, 15, 10, 10);

    จากตัวอย่างเราสามารถทำได้ง่ายๆโดยใช้ property PageSize และกำหนดให้ทำการพลิกกระดาษ โดยคำสั่ง Rotate() ต่อท้ายขนาดกระดาษที่เราได้เลือกเอาไว้ ต่อมาเมื่อเราทำการตั้งค่ากระดาษเรียบร้อยแล้ว เราต้องทำการเปิดตัวเอกสารของเรา ให้สามารถบันทึกข้อมูลตามที่เราต้องการลงไปได้ ด้วยคำสั่ง Open() และทำการปิดเอกสารเมื่อทำการบันทึกข้อมูลเสร้จเรียบร้อย ด้วยคำสั่ง Close() มาดูตัวอย่างกัน

    Document pdfDoc = new Document(PageSize.A4, 30, 30, 20, 20);
    pdfDoc.Open();
    ...
    pdfDoc.Close();

    นี้ก็ถือว่าจบส่วนของการสร้างเอกสารและตั้งค่ากระดาษแล้วครับ ส่วนต่อมาเป็นส่วนการเขียนเอกสารจริงผ่าน Function ของภาษาที่เราใช้งานกัน โดยตัวอย่างของผู้เขียนนั้นใช้งานภาษา C# บน .Netframework ไปดูตัวอย่างการเขียนได้เลยครับ

    Document pdfDoc = new Document(PageSize.A4.Rotate(), 20, 15, 10, 10);
    PdfWriter.GetInstance(pdfDoc, System.Web.HttpContext.Current.Response.OutputStream);
    pdfDoc.Open();
    ...
    pdfDoc.Close();
    HttpContext.Current.Response.ContentType = "application/pdf";
    HttpContext.Current.Response.AddHeader("content-disposition", "attachment; filename=StatSummary_" + DateTime.Now.ToString("yyyyMMdd") + ".pdf");
    System.Web.HttpContext.Current.Response.Write(pdfDoc);
    

    จากตัวอย่าง ผู้เขียนได้ทำการระบุว่าเอกสารที่เราสร้างนั้นกำหนด ContentType เป็น application/pdf เพื่อ Response เป็น Pdf ในบรรทัดที่ 6 และทำการตั้งชื่อเอกสาร ในบรรทัดที่ 7 สุดท้ายก็ทำการสร้างเอกสารและบันทึกไว้บนเครื่อง ในบรรทัดที่ 8 ก็ถือว่าจบในส่วนของการสร้างเอกสารแล้วครับผม


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

  • การกำหนดรูปแบบเอกสารด้วย reStructuredText

    การสร้างเอกสารด้วย reStructuredText syntax ทำให้เอกสารที่พัฒนาง่ายในการอ่าน จัดรูปแบบได้ตามที่เห็น รูปแบบของ markup เป็น plaintext ซึ่งจะใช้ parser ในการแปลงให้อยู่ในรูปแบบเอกสารที่ต้องการเช่น html หรือ pdf เป็นต้น

    การกำหนดรูปแบบ (Text Formatting)

    1. Paragraphs

    Paragraphs คือ block พื้นฐานของ reStructuredText ซึ่งแต่ละ paragraphs จะถูกแยกด้วย blank line 1 บรรทัด หรือมากกว่าหนึ่งก็ได้ ซึ่งย่อหน้ามีผลกับ reStructuredText ดังนั้นในการกำหนดบรรทัดใน paragraph เดียวกันจะต้องมี ย่อหน้าด้สนซ้ายเท่ากันในระดับเดียวกัน.

    2. Inline markup และ special character

    เราสามารถใช้ตัวอักษรพิเศษในการกำหนดรูปแบบข้อความมีอยู่ด้วยกันหลายตัว  ตัวอักษรพิเศษ * ถูกใช้ในการกำหนดรูปแบบตัวอักษรตัวหนา และ ตัวอักษรตัวเอียง ดังตัวอย่างด้านล่าง

    • ตัวหนา **ภาษาไทย**  จะแสดงผลคือ  ภาษาไทย
    • ตัวเอียง *ภาษาไทย*   จะแสดงผลคือ  ภาษาไทย

    ตัวอักษรพิเศษ backquote  ` จะใช้ในการกำหนดตัวอย่าง  code โดยการใช้งานดังนี้

    ``code sample``

    แต่ถ้าต้องการใช้ * และ `  ในเอกสารด้วยซึ่งจะทำให้สับสนกับ inline markup ได้ ดังนั้นจึงใช้  backslash นำหน้าสำหรับ * และ ` ที่จะใช้แสดงผลของเอกสาร

    3. Lists and Quote-like blocks

    การกำหนด list สามารถทำได้โดยการใช้ * นำหน้า

    * bulleted list
    * bulleted list
    * bulleted list

    สำหรับ numbered list ก็ให้ใช้ตัวเลขนำหน้า

    1. numbered list
    2. numbered list

    ถ้าต้องการ list ที่กำหนดเลขโดยอัตโนมัติให้ใช้ # นำหน้า

    #. numbered list
    #. numbered list

    การกำหนด list ซ้อนกันหลายๆชั้นสามารถทำได้ แต่ต้องแยกแต่ละ list ออกด้วย blank line

    *. bulleted list
    *. bulleted list
        *. bulleted list
        *. bulleted list
    *. bulleted list

    4. Source code

    การกำหนด code block ทำได้โดยใช้ special marker :: ที่ตอนจบของ paragraph และจะต้องแยกจากส่วนอื่นด้วย blank line เช่นเดียวกับ paragraph ทั่วไป

    This is a normal text paragraph. The next paragraph is a code sample::
    
                public class reStructuredTest {
                        public reStructuredTest(){
                        }
                }
    

    5. Table

    การสร้างตารางทำได้ในสองรูปแบบคือแบบ grid table และ simple table โดยการสร้างตารางแบบ grid table ทำได้ด้วยการวาดตารางด้วยตัวเอง

    +------------------------+------------+----------+----------+
    | Header row, column 1   | Header 2   | Header 3 | Header 4 |
    | (header rows optional) |            |          |          |
    +========================+============+==========+==========+
    | body row 1, column 1   | column 2   | column 3 | column 4 |
    +------------------------+------------+----------+----------+
    | body row 2             | ...        | ...      |          |
    +------------------------+------------+----------+----------+
    

    สำหรับ Simple tables จะเขียนง่ายกว่ารูปแบบแรก แต่มีข้อมจำกัดคือ จะต้องมีมากกว่า 1 row และ column แรกไม่อนุญาติให้มีหลายบรรทัด

    =====  =====  =======
    A      B      A and B
    =====  =====  =======
    False  False  False
    True   False  False
    False  True   False
    True   True   True
    =====  =====  =======
    

    6. Hyperlinks

    การกำหนด hyperlink ทำได้โดยการกำหนดรูปแบบดังนี้

    `Link text <http://example.com/>`_

    section header กำหนดโดยใช้การทำ underlining โดยที่ความยาวของ underlining จะต้องเท่ากับจำนวนตัวอักษรของ header

    =================
    This is a heading
    =================
    

    การกำหนดระดับของ header จะทำได้โดย

    • # ร่วมกับ overline  สำหรับกำหนด  part header
    • * ร่วมกับ overline สำหรับกำหนด chapter header
    • = สำหรับกำหนด section header
    • - สำหรับกำหนด subsection header
    • ^ สำหรับกำหนด subsubsection header
    • ” สำหรับกำหนด paragraph header

     

    อ้างอิง

    1. http://www.sphinx-doc.org/en/1.5.1/rest.html
    2. http://thomas-cokelaer.info/tutorials/sphinx/rest_syntax.html

  • ทดสอบเว็บบน Browser ทุกตัวง่ายนิดเดียว

    ทดสอบเว็บผ่าน Browser
    หลังจากที่ได้มีการพัฒนาหรือสร้างเว็บขึ้นมาเรียบร้อยแล้วนั้น สิ่งแรกๆ ที่ต้องทำคือทดสอบเว็บของเราว่าสามารถที่จะแสดงผลผ่าน Browser ได้ดีหรือไม่ และแสดงผลได้ดีกับทุก Browser หรือไม่ เช่น Google Chrome , Firefox หรือจะเป็น Internet Explorer ซึ่ง Browser แต่ละตัวนั้นก็มีหลากหลายเวอร์ชันมาก และที่เราต้องพยายามทดสอบให้ได้มากที่สุดก็เพราะว่า เราไม่สามารถรู้ได้เลย ว่าลูกค้าหรือผู้ใช้เว็บของเรานั้นจะใช้เครื่องมือ หรือ Browser ตัวไหนเป็นหลัง ดังนั้นการทดสอบเว็บบน Browser ทุกตัวไม่ใช่เรื่องง่ายเลยจริงๆ

    ทำอย่างไรให้การทดสอบผ่าน Browser ทุกตัวเป็นเรื่องง่าย

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

    หลักๆ จากที่ศึกษาค้นคว้าเบื้องต้นพบว่าปัจจุบันมี Cloud Browser เปิดให้บริการมากมาย เช่น Saucelab, BrowserStack, Browserling, Ghostlab หรือ CrossBrowserTesting เป็นต้น

    สำหรับวันนี้จะขอนำเสนอหน้าตาของ BrowserStack กันก่อนละกัน

    • เราจะต้องสมัครสมาชิกกันก่อน โดยจะมีแบบ Free trial ให้เราทดลองใช้งาน สมัครเสร็จแล้วก็ Login เข้าไปทดลองใช้งานกันได้เลย

     

    • หลังจากสมัครสมาชิกทดลองใช้ฟรีกันเรียบร้อยแล้ว ก็จะพบกับหน้าตาของเจ้า BrowserStack แบบนี้

     

    • เราสามารถเลือกได้เลยว่าจะทดสอบเว็บกับระบบปฏิบัติการไน และ Browser อะไร

     

    • ตัวอย่างเช่นเลือก ระบบปฏิบัติการ Mac OS X Mavericks และ Browser Safari 7.1 ก็จะได้ตัวอย่างหน้าจอ
      แบบด้านล่าง

     

     

     

    • ในหน้าจอที่เรากำลังทดสอบก็จะมี Tool เล็กๆ ให้เราสามารถจัดการหน้าจอได้ เช่นสามารถ Switch เพื่อเปลี่ยนเป็นระบบปฏิบัติการ หรือ Browser อื่นๆ สามารถปรับ Resolutions
      ของหน้าจอได้ สามารถ Create a bug สามารถสร้าง Issue Tracker สามารถตั้งค่าอื่นๆ
      หรือตรวจสอบ Features ของตัว BrowserStack ได้ เป็นต้น

     

     

     

     

    สุดท้ายแล้วสำหรับเพื่อนๆ หรือใครที่มีปัญหายุ่งยากในการทดสอบเว็บให้ครบทุก Browser ก็สามารถลองเอาเจ้าตัว BrowserStack ไปใช้งานกันดู เผื่อบางทีอาจจะช่วยระยะเวลา หรือปัญหาต่างๆ ได้บ้างไม่มากก็น้อย ^ ^

    แหล่งความรู้อ้างอิง
    – http://soraya.in.th/2013/04/08/browserstack-ie/
    – https://medium.com/tag/browserstack
    – https://chittakorn.com/do-you-know/browser-testing/
    – http://www.designil.com/free-internet-explorer-mac.html

  • การวิเคราะห์ข้อมูล (What-if Analysis)

                ในหัวข้อนี้เราจะมาพูดถึงการวิเคราะห์ข้อมูลโดยใช้ What-if ซึ่งเป็นเครื่องมือการวิเคราะห์ที่อยู่ใน Excel การวิเคราะห์ข้อมูลแบบ What-if เป็นการเอาสูตรหรือข้อมูลที่มีมาวิเคราะห์เพื่อหาทางเลือกจากสถานการณ์ต่างๆ โดยมีการวิเคราะห์ 3 แบบ คือ สถานการณ์สมมติ(Scenario), ตารางข้อมูล(Data Table) และการค้นหาค่าเป้าหมาย(Goal Seek) สถานการณ์สมมติและตารางข้อมูลจะรับชุดของค่าข้อมูลเข้า(Input) และประเมินล่วงหน้า เพื่อหาผลลัพธ์ที่เป็นไปได้ ส่วนการค้นหาค่าเป้าหมายต่างจากสถานการณ์สมมติและตารางข้อมูลตรงที่ นำผลลัพธ์มาประเมินย้อนกลับ เพื่อหาค่าข้อมูลเข้าที่เป็นไปได้ที่ทำให้เกิดผลลัพธ์นั้นๆ

    1. การค้นหาค่าเป้าหมาย(Goal Seek)

                ปกติเวลาคำนวณเราจะคำนวณตามลำดับ เช่น ยอดขาย–ค่าใช้จ่าย = กำไร แต่ Goad Seek ใช้การระบุผลลัพธ์ที่ต้องการ(Output) แล้วคำนวณค่าข้อมูลเข้า(Input) เพื่อให้ได้ผลลัพธ์ตามที่เราต้องการ

                ตัวอย่าง1 การคำนวณเงินกู้ ปกติจะคำนวณจากเงินต้น ระยะเวลาที่กู้ และดอกเบี้ย และใส่สูตรด้วยฟังก์ชัน PMT (ดูภาพที่ 1) ซึ่งจะได้จำนวนเงินที่ต้องจ่ายในแต่ละเดือน (ดูภาพที่ 2)

    ภาพที่ 1 คำนวณอัตราผ่อนชำระต่องวด

    ภาพที่ 2 จำนวนเงินที่ต้องจ่ายในแต่ละเดือน

     

    เงื่อนไขที่ 1 : ถ้ามีต้องการผ่อนต่อเดือน 10,000 บาท ในระยะเวลา 10 ปี สามารถใช้ Goal Seek คำนวณให้ได้ว่า จะสามารถกู้เงินได้เท่าไหร่? ไปที่ Data > What-if Analysis > Goal Seek (ดูภาพที่ 3)

    ภาพที่ 3 เลือกคำสั่ง Goal Seek

    ในหน้าต่าง Goal Seek (ดูภาพที่ 4) :

    Set cell – cell ที่จะใช้ตั้งค่า โดยคลิกเลือก cell ที่เขียนสูตรเอาไว้ (ในตัวอย่างนี้คือ B5)

    To value – ระบุค่าเป้าหมายที่ต้องการ (ต้องการผ่อนเดือนละ 10,000)

    By changing cell – ระบุ cell ที่ต้องการให้เปลี่ยนแปลงค่าตามเป้าหมายที่กำหนดไว้ (จำนวนเงินที่กู้ได้)

    ภาพที่ 4 กำหนดค่าเป้าหมาย

    สรุป ถ้าต้องการผ่อนเดือนละ 10,000 เป็นระยะเวลา 10 ปี จะต้องกู้เงินจำนวน 949,363 บาท (ดูภาพที่ 5)

    ภาพที่ 5 คำตอบที่ได้ของเงื่อนไขที่ 1

    เงื่อนไขที่ 2 : ถ้าต้องการกู้เงิน 1,000,000 บาท และผ่อนชำระเดือนละ 10,000 บาท จะต้องใช้เวลาเท่าไหร่? (ดูภาพที่ 6)

    ภาพที่ 6 กำหนดค่าเป้าหมาย

    สรุป ถ้าต้องการกู้เงิน 1,000,000 บาท และผ่อนชำระเดือนละ 10,000 บาท จะต้องใช้เวลาประมาณ 129 เดือน (ดูภาพที่ 7)

    ภาพที่ 7 ระยะเวลาผ่อนชำระ(เดือน)

    2. สถานการณ์สมมติ(Scenario)

                ตัวอย่าง2 เปิดร้านขายเบเกอรี่มีเค้กขายอยู่ 12 ชนิด ในการวิเคราะห์กำไรจากการขาย (ดูภาพที่ 8) อาจแบ่งยอดขายได้หลายกรณี เช่น กรณีขายดี(Best Case), กรณีขายไม่ค่อยดี(Worst Case) และกรณีที่น่าจะเป็น(Most Likely) เป็นต้น

     ภาพที่ 8 ตัวอย่างตารางข้อมูลสำหรับคำนวณโดยใช้ Scenario

     

    ไปที่ Data > What-if Analysis > Scenario Manager (ดูภาพที่ 9) จะมีหน้าต่าง Edit Scenario ขึ้นมาให้กด Add…

    • Scenario Name ชื่อของ Scenario
    • Changing cells เป็นเซลล์ที่จะเปลี่ยนค่า ในตัวอย่างเป็นจำนวนเค้ก

    โดยให้ทำการ Add ทั้ง 3 Case – Best Case(จำนวนมากกว่า 100 ชิ้น), Worst Case(อย่างละ 50 ชิ้น), Most Likely Case(อย่างละ 100 ชิ้น)

    ภาพที่ 9 Add Scenario

    ภาพที่ 10 ตัวอย่างกำหนดค่าให้ Most Likely

    กดปุ่ม Summary เพื่อสรุปค่า Scenario จะมีหน้าต่าง Scenario Summary ขึ้นมา ให้เลือก Report type ที่จะแสดงในรายงาน ซึ่งมี 2 แบบ คือ

    • Scenario Summary เป็นตารางสรุปผล Scenario ในแต่ละกรณี (ดูภาพที่ 11)
    • Scenario PivotTable Report เป็น PivotTable แสดงรายละเอียดของ Scenraio

    ภาพที่ 11 Scenario Summary

    3. ตารางข้อมูล(Data Table)

                จากตัวอย่าง1 หากต้องการทราบว่าช่วงเงินกู้ระหว่าง 800,000-1,700,000 บาท ถ้าให้ระยะเวลาผ่อน 10 ปีด้วยกันจะต้องผ่อนเดือนละเท่าไหร่??

                ใส่ค่าช่วงของเงินกู้ที่ต้องการเปลี่ยนแปลง ส่วนจำนวนเงิน 10,533 ให้กด = แล้ว Link ไปที่ช่องผลลัพธ์ที่คำนวณไว้แล้ว ในที่นี้ = B5 ของตัวอย่างที่1 ลากคลุม cell ตามภาพที่ 12 จากนั้นไปที่ Data > What-if Analysis > Data Table… ที่นี้เราจะลองเปลี่ยนยอดเงินกู้ ซึ่งเรียงกันอยู่ในรูปแบบ Column ดังนั้นเราต้องใส่ค่า “จำนวนที่กู้” ลงใน Column Input Cell จะได้ผลลัพธ์ดังภาพที่ 13

    ภาพที่ 12 แสดงวิธีคำนวณด้วยคำสั่ง Data Table

    ภาพที่ 13 ยอดผ่อนต่อเดือนตามจำนวนเงินกู้

    สมมติเราอยากรู้ว่าถ้ายอดเงินกู้ และ ระยะเวลาเปลี่ยน จำนวนเงินที่จะต้องผ่อนต่อเดือนจะเป็นเท่าไหร่??

    ให้ Copy ช่วงเงินกู้มาตั้งไว้ในแนว Column เหมือนเดิม เพิ่มเติมคือระยะเวลาให้ใส่แนว Row(ดูภาพที่ 14) และผลลัพธ์ในภาพที่ 15

    ภาพที่ 14 แสดงการคำนวณ Data Table 2 Input

    ภาพที่ 15 ผลลัพธ์การเปลี่ยนแปลงยอดผ่อนต่อเดือน

     

     

    สามารถอ่านข้อมูลและศึกษาเพิ่มเติมได้

    https://support.office.com/en-us/article/Introduction-to-What-If-Analysis