หน้าเว็บ

แสดงบทความที่มีป้ายกำกับ Array แสดงบทความทั้งหมด
แสดงบทความที่มีป้ายกำกับ Array แสดงบทความทั้งหมด

วันพุธที่ 31 สิงหาคม พ.ศ. 2554

การค้นหาตัวเลขทะเบียนรถที่ถูกโฉลก

สำหรับท่านที่ต้องการเลือกเลขทะเบียนรถเองโดยมีเงื่อนไขในการคัดเลือก ยกตัวอย่างเช่นต้องการให้

  1. ให้รวมตัวเลขทุกตัวแล้วได้ค่าเป็น 9, 18, 27 หรือ 36
  2. สามารถคัดชุดที่มีตัวเลขที่ไม่ต้องการออกไปได้ด้วย ยกตัวอย่างเช่นไม่รวมตัวเลขที่มีค่าต่อไปนี้ 0, 3, 7, 8

การหาค่าดังกล่าวสามารถใช้สูตรหรือ VBA มาคำนวณได้ครับ

กรณีใช้สูตรในการคำนวณมีวิธีการดังนี้

  1. เปิดสมุดงานใหม่แล้วเลือกชีทว่าง
  2. ที่ A1 คีย์ No. และ ที่ B1 คีย์ Select เพื่อเป็นชื่อ Field
  3. ที่ A2 คีย์ Row()-1 > Copy ลงด้านล่างตามต้องการ
  4. ที่ B2 คีย์สูตร
    =IF(MIN(LEN(SUBSTITUTE(A2,{0,3,7,8},"")))<LEN(A2),"",IF(ISNUMBER(MATCH(SUM(MID(A2,ROW(INDIRECT("1:"&LEN(A2))),1)+0),{9,18,27,36},0)),SUM(MID(A2,ROW(INDIRECT("1:"&LEN(A2))),1)+0),""))
    Ctrl+Shift+Enter > Copy ลงด้านล่าง

กรณีใช้ VBA ในการคำนวณมีวิธีการดังนี้

  1. กดแป้น Alt+11 เพื่อเปิดหน้าต่าง VBE
  2. คลิกเมนู Insert > Module
  3. Copy Code ด้านล่างไปวาง

    Sub ListNum()
    Dim i As Integer, bln As Boolean
    Dim c As Integer, j As Integer
    Dim a As String, s As Integer
    For i = 1 To 9999
    bln = False
    s = 0
    For j = 1 To Len(CStr(i))
    a = Mid(i, j, 1)
    Select Case a
    Case 0, 3, 7, 8
    bln = True
    Exit For
    Case Else
    s = s + a
    End Select
    Next j
    If bln = False Then
    Select Case s
    Case 9, 18, 27, 36
    c = c + 1
    Cells(c + 1, 1) = i
    End Select
    End If
    Next i
    End Sub


  4. กดแป้น Alt+Q เพื่อกลับมายังโปรแกรม Excel
  5. กดแป้น Alt+F8 > เลือก ListNum > Run

โปรแกรมจะทำการ Run ตัวเลขมาให้ตามเงื่อนไขที่ต้องการ


ภาพตัวอย่างการใช้งาน


ListNum

วันพุธที่ 9 ธันวาคม พ.ศ. 2552

การตัดข้อความกรณีที่คำนำหน้านามติดกับชื่อ

กรณีที่คำนำหน้านามไม่ติดกับชื่อ สามารถใช้ Excel จัดการได้ง่าย ๆ ครับไม่ว่าจะด้วยสูตรหรือใช้ Text to columns แต่หากเมื่อใดที่คำนำหน้านามมีความหลากหลายทั้งยังอยู่ติดกับชื่อแล้ว การจัดการจะยุ่งยากขึ้นครับ

ตามตัวอย่างนี้จะแสดงวิธีการหนึ่งที่จะแยกคำนำหน้านาม ชื่อ และนามสกุลออกจากกันในกรณีที่คำนำหน้านามมีความหลากหลาย ซึ่งจะใช้สูตร Array เข้ามาช่วยครับ

ภาพประกอบการตัดข้อความกรณีมีคำนำหน้านามติดกับชื่อ

NameSurename 
ซึ่งมีขั้นตอนดังนี้

  1. จากภาพให้ทำการกรอกคำนำหน้าชื่อที่คิดว่าจะมีทั้งหมดก่อนที่ F2:F12
  2. แล้วคีย์ในแต่ละเซลล์ดังนี้
    1. เซลล์ D3 คีย์สูตรเพื่อตัดนามสกุลมาแสดง
      =RIGHT(A3,LEN(A3)-FIND(" ",A3))
      Enter
    2. เซลล์ C3 คีย์สูตรเพื่อตัดชื่อมาแสดง
      =SUBSTITUTE(RIGHT(A3,MIN(LEN(SUBSTITUTE(A3,$F$2:$F$13,"")))),D3,"") Ctrl+Shift+Enter
    3. เซลล์ B3 คีย์สูตรเพื่อตัดคำนำหน้านามมาแสดง
      =SUBSTITUTE(SUBSTITUTE(A3,C3,""),D3,"")
      Enter

ตัวอย่างวิธีคิดหลักๆ จากสูตรในเซล C3

  1. เปลี่ยนคำนำหน้านามให้เป็นค่าว่าง ซึ่งจะเหลือเพียงชื่อและนามสกุล แล้วนับอักขระ จะได้จำนวนอักขระไม่รวมคำนำหน้านาม คำไหนที่ถูกเปลี่ยนโดยเอาคำนำหน้านามออกไปแล้ว จำำนวนอักขระจะน้อยลง เอาค่าที่น้อยที่สุดไปกระทำในข้อที่ 2 (ดูตัวอย่า่งการแกะสูตรด้านล่างประกอบ)
  2. ใช้สูตร Right() เพื่อตัดอักขระด้านขวาของเซลต้นแหล่งให้เหลือเท่ากับจำนวนที่นับได้ในข้อ 1 ผลลัพธ์จะได้ชื่อและนามสกุล
  3. ใช้สูตร Substitute() เพื่อเปลี่ยนนามสกุล(ซึ่งหาไว้ก่อนแล้วซึ่งก็คือเซล D3)ให้เป็นค่าว่างโดยต้องการให้เหลือแค่ชื่อ

ตัวอย่างการแกะสูตร จากสูตรที่ C3 ซึ่งเป็นสูตร Array

จากสูตร =SUBSTITUTE(RIGHT(A3,MIN(LEN(SUBSTITUTE(A3,$F$2:$F$12,"")))),D3,"")

  1. เปลี่ยนคำนำหน้านามให้เป็นค่าว่าง
    คลุม SUBSTITUTE(A3,$F$2:$F$12,"") แล้วกดแป้น F9 จะได้
    =SUBSTITUTE(RIGHT(A3,MIN(LEN({"นางสาวมานี สวยสม";"สาวมานี สวยสม";"มานี สวยสม";"นางสาวมานี สวยสม";"นางสาวมานี สวยสม";"นางสาวมานี สวยสม";"นางสาวมานี สวยสม";"นางสาวมานี สวยสม";"นางสาวมานี สวยสม";"นางสาวมานี สวยสม";"นางสาวมานี สวยสม"}))),D3,"")
  2. นับอักขระที่เหลือจากการเปลี่ยนคำนำหน้าชื่อให้เป็นค่าว่างแล้ว
    คลุม LEN({"นางสาวมานี สวยสม";"สาวมานี สวยสม";"มานี สวยสม";"นางสาวมานี สวยสม";"นางสาวมานี สวยสม";"นางสาวมานี สวยสม";"นางสาวมานี สวยสม";"นางสาวมานี สวยสม";"นางสาวมานี สวยสม";"นางสาวมานี สวยสม";"นางสาวมานี สวยสม"}) แล้วกดแป้น F9 จะได้
    =SUBSTITUTE(RIGHT(A3,MIN({16;13;10;16;16;16;16;16;16;16;16})),D3,"")
  3. หาค่าที่น้อยที่สุดหลังจากนับแล้ว
    คลุม MIN({16;13;10;16;16;16;16;16;16;16;16}) แล้วกดแป้น F9 จะได้
    =SUBSTITUTE(RIGHT(A3,10),D3,"")
    คำตอบคือ "มานี "
    จะเห็นได้ว่าคำว่า "มานี " มีวรรคต่อท้ายมา 1 อักขระ ซึ่งสามารถทีจะใช้ฟังก์ชั่น Trim ครอบสูตรที่ C3 และ B3 เพื่อที่จะตัดช่องว่างนี้ออกไปได้ครับ ซึ่งจะได้สูตรเป็น
    1. เซลล์ C3
      =TRIM(SUBSTITUTE(RIGHT(A3,MIN(LEN(SUBSTITUTE(A3,$F$3:$F$13,"")))),D3,""))
      Ctrl+Shift+Enter
    2. เซลล์ B3
      =TRIM(SUBSTITUTE(SUBSTITUTE(A3,C3,""),D3,""))
      Enter

การใช้สูตรสุ่มข้อมูลเป็นชุด ๆ โดยกำหนดได้ว่าให้ไม่ซ้ำกันภายในชุด

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

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

ภาพตัวอย่างการ Random ด้วยสูตรตามด้านล่างครับ

RandomInAdvanced 

จากภาพด้านบนเราสมมุติว่าข้อมูลมีชุดละ 2 บรรทัด และโดยชุดแรกคือ C2:C3, ชุดที่สองคือ C4:C5 เป็นต้น และจะทำการสุ่มโดยนำข้อมูลสีที่ E3:E4 เข้าแสดงแต่ต้องไม่ซ้ำสีกันภายในชุดเดียวกัน

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

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

ช่วงเซลล์ที่ต้องการสุ่มในฟังก์ชั่น Index ก็เช่นกัน สามารถทำให้ Dynamic โดยการให้ชื่อกับช่วงเซลล์แบบ Dynamic ได้

ตามรูป ที่ C2 คีย์

=Index($E$3:$E$4,Small(If(Countif(If(Mod(Rows($C$2:C2)-1,2)=0,$C$1:$C$1,Offset(C1,0,0,-Mod(Rows($C$2:C2)-1,2),1):C1),$E$3:$E$4)=0,Row($E$3:$E$4)-Row($E$3)+1),Int((2-Mod(Rows($C$2:C2)-1,2))*Rand())+1))

การกดแป้นให้รับสูตรต้องกด 3 แป้นคือ Ctrl+Shift+Enter ถ้ากดแป้นถูกต้องจะเห็นปีกกาคร่อมสูตร จากนั้น Copy ลงด้านล่าง

การสรุปข้อมูลจากฐานข้อมูลที่แบ่งเป็นช่วง ๆ

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

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

จากภาพด้านล่างจะเป็นการสรุปข้อมูลตามที่ต้องการโดยการเลือก Region และ Product โปรแกรมจะแสดงยอดรวม ทั้งแจกแจงรายการทั้งหมดที่ตรงตาม Region และ Product

ภาพตัวอย่างการสรุปข้อมูลจากฐานข้อมูลที่แบ่งเป็นช่วง ๆ

AdvancedOffsetMatch

โดยมีวิธีการและขั้นตอนดังนี้

A. List รายการของ Product ทั้งหมด

  1. นับ Product ที่มีทั้งหมดโดยไม่นับค่าที่ซ้ำ H1 คีย์
    =SUM(IF(FREQUENCY(IF(ISNUMBER($B$1:$B$39),MATCH("~"&$A$1:$A$39,$A$1:$A$39&"",0)),ROW($B$1:$B$39)-ROW($B$1)),1))
    Ctrl+Shift+Enter
  2. List รายการ Product ทั้งหมดโดยไม่เอาค่าซ้ำที่ H2 คีย์
    =IF(ROWS($H$2:H2)<=$H$1,INDEX($A$1:$A$39,SMALL(IF(FREQUENCY(IF(ISNUMBER($B$1:$B$39),MATCH("~"&$A$1:$A$39,$A$1:$A$39&"",0)),ROW($A$1:$A$39)-ROW($A$1)+1),ROW($A$1:$A$39)-ROW($A$1)+1),ROWS($H$2:H2))),"")
    Ctrl+Shift+Ener > Copy ลงด้านล่าง

B. List รายการ Region ทั้งหมด

  1. นับจำนวน Region โดยไม่เอาค่าซ้ำที่ G1 คีย์
    =SUMPRODUCT(--(B1:B39=""),--(A1:A39<>""))
    Enter
  2. List Region ทั้งหมด G2 คีย์
    =IF(ROWS($G$2:G2)<=$G$1,INDEX($A$1:$A$39,SMALL(IF($B$1:$B$39="",IF($A$1:$A$39<>"",ROW($B$1:$B$39)-ROW($B$1)+1)),ROWS($G$2:G2))),"")
    Ctrl+Shift+Ener > Copy ลงด้านล่าง

C. หาตำแหน่งเซลล์ว่างสุดท้ายในบรรทัดด้านล่างถัดจาก Region ที่เลือกใน E2 ที่ E1 คีย์

=SMALL(IF(A1:A39="",ROW(A1:A39)-ROW(A1)+1),MATCH(E2,G2:G7,0))
Ctrl+Shift+Ener

D. List รายการที่ตรงตามเงื่อนไขทั้ง Region และ Prod ที่เลือกใน E2 และ E3 ตามลำดับ

  1. นับว่าตรงตามเงื่อนไขทั้งหมดมีจำนวนเท่าไรที่ D6 คีย์
    =COUNTIF(OFFSET(A2,MATCH(E2,$A$1:$A$39,0),0,E1-MATCH(E2,$A$1:$A$39,0)),E3)
    Enter
  2. List Product ทั้งหมดที่ตรงตามเงื่อนไข ที่ D8 คีย์
    =IF(ROWS($D$8:D8)<=$D$6,INDEX(OFFSET($A$2,MATCH($E$2,$A$1:$A$39,0),0,$E$1-MATCH($E$2,$A$1:$A$39,0)),SMALL(IF(OFFSET($A$2,MATCH($E$2,$A$1:$A$39,0),0,$E$1-MATCH($E$2,$A$1:$A$39,0))=$E$3,ROW(OFFSET($A$2,MATCH($E$2,$A$1:$A$39,0),0,$E$1-MATCH($E$2,$A$1:$A$39,0)))-MATCH($E$2,$A$1:$A$39,0)-1),ROWS($D$8:D8))),"")
    Ctrl+Shift+Enter > Copy ลงด้านล่าง
  3. List Value ทั้งหมดที่ตรงตามเงื่อนไข ที่ E8 คีย์
    =IF(ROWS($D$8:D8)<=$D$6,INDEX(OFFSET($B$2,MATCH($E$2,$A$1:$A$39,0),0,$E$1-MATCH($E$2,$A$1:$A$39,0)),SMALL(IF(OFFSET($A$2,MATCH($E$2,$A$1:$A$39,0),0,$E$1-MATCH($E$2,$A$1:$A$39,0))=$E$3,ROW(OFFSET($A$2,MATCH($E$2,$A$1:$A$39,0),0,$E$1-MATCH($E$2,$A$1:$A$39,0)))-MATCH($E$2,$A$1:$A$39,0)-1),ROWS($D$8:D8))),"")
    Ctrl+Shift+Enter > Copy ลงด้านล่าง

E. สูตรหายอดรวมรายการที่ตรงตามเงื่อนไขโดยไม่ต้องแจกแจงรายการออกมาก่อน ที่ E4 คีย์

=SUMIF(OFFSET(A2,MATCH(E2,$A$1:$A$39,0),0,E1-MATCH(E2,$A$1:$A$39,0)),E3,OFFSET(B2,MATCH(E2,$A$1:$A$39,0),0,E1-MATCH(E2,$A$1:$A$39,0)))
Enter

วันอาทิตย์ที่ 9 พฤศจิกายน พ.ศ. 2551

แยกภาษาไทยออกจากอังกฤษหรืออังกฤษออกจากไทย

กรณีที่มีการเขียนภาษาอังกฤษต่อด้วยภาษาไทยหรือตรงกันข้ามกัน และต้องการแยกคำออกมา สามารถใช้สูตรในการแยกภาษาออกมาได้ครับ สมมุติ

  1. เซลล์ A1 มีคำว่า Bangkokกรุงเทพมหานคร ต้องการแยก Bangkok และกรุงเทพมหานครให้อยู่คนละเซลล์สามารถทำได้ดังนี้
    1. เซลล์ B1 แยก Bangkok ออกมาแสดงโดยคีย์สูตร
      =LEFT(A1,MATCH("zzz",MID(A1,ROW(INDIRECT("1:"&LEN(A1))),1)))
      Ctrl+Shift+Enter
    2. เซลล์ C1 แยกกรุงเทพมหานครออกมาแสดงโดยคีย์สูตร
      =Substitute(A1,B1,"")
      Enter
  2. เซลล์ A1 มีคำว่า กรุงเทพมหานครBangkok ต้องการแยก กรุงเทพมหานคร และ Bangkok ให้อยู่คนละเซลล์สามารถทำได้ดังนี้
    1. เซลล์ B1 แยกกรุงเทพมหานครออกมาโดยคีย์สูตร
      =LEFT(A1,MIN(SEARCH(CHAR(ROW(INDIRECT("65:90"))),A1&"abcdefghijklmnopqrstuvwxyz")-1))
      Ctrl+Shift+Enter
    2. เซลล์ C1 แยก Bangkok ออกมาแสดงโดยคีย์สูตร
      =Substitute(A1,B1,"")
      Enter

Note: สูตรที่ B1 ทั้งสองสูตรเป็นสูตรแบบอาร์เรย์ การคีย์ให้รับสูตรจะต้อง Ctrl+Shift+Enter ครับ