PDA

View Full Version : เรื่อง data input & enter key ครับ



galahut
12 Jun 2007, 13:51
คือว่าผมได้รับงานมาชิ้นนึงคือการบันทึกชั่วโมงทำงานของพนักงาน
โดยลักษณะคร่าวๆดังไฟล์ที่แนบไว้ ผมคิดไว้ว่าจะแยกงานออกเป็น 2 ส่วน
ส่วนที่หนึ่งส่วนกรอกข้อมูล กับส่วนสองส่วนรับค่าไปเรียงตามข้อมูลที่ได้รับมา
ซึ่งส่วนที่สองนั้นผมคิดได้แล้วครับ จึงอยากเรียนถามในส่วนที่หนึ่งดังนี้
1) จะต้องใช้คำสั่งอะไร เพื่อที่ว่าพอกด enter แล้วให้เซลที่เราต้องการ active ( อาจใช้คำพูดไม่ถูกนะครับ คือกรอกข้อมูลช่องแรกเสร็จแล้วกดenter มันจะfocus ไปยังเซลที่เราต้องการเพื่อกรอกข้อมูลอื่นๆต่อ )
2) ทำยังไงให้มีการตรวจจับการกระทำต่างๆอยู่ตลอดเวลาครับ เพราะปรกติที่ผมเคยทำมา เวลารันมาโครเพื่อคำนวนหรือทำงานต่างๆก็จะรันไปทีเดียวแล้วจบเลย เราต้องทำยังไงให้มีการรันมาโครเพื่อตรวจจับการกระทำต่างๆอยู่ตลอดเวลาหรือ รันทุกครั้งที่กดenter หรือรันอัตโนมัตเมื่อเราเปลี่ยนแปลงข้อมูลบางตัว ครับ
รบกวนให้คำปรึกษาด้วยนะครับ อาจารย์ทุกท่าน ขอบคุณครับ
ส่วนถ้าคำพูดหรือสำนวนตรงไหนผิดพลาดประการใด ก็ขออภัยไว้นะที่นี้นะครับ

ผมขอแนะนำโค้ด VBA ที่เกี่ยวข้องกับปุ่ม Enter สักเล็กน้อยครับ

ขอบคุณครับสำหรับคำแนะนำ จะนำไปทดลองครับ

มิตรภาพ
12 Jun 2007, 19:48
ผมขอแนะนำโค้ด VBA ที่เกี่ยวข้องกับปุ่ม Enter สักเล็กน้อยครับ

Application.MoveAfterReturn = False ยกเลิกการทำงานของปุ่ม กดแล้วไม่ไปใหน จะไปตามที่เขียนโค้ดบังคับไว้เท่านั้น
Application.MoveAfterReturn = True ให้ปุ่มทำงานตามแบบเดิมของเอ็กเซล
Application.MoveAfterReturnDirection = xlDown กดแล้วเลื่อนลง และยังใช้ xlUp,xlToLeft, xlToRight เพื่อให้ไปยังทิศทางนั้นๆได้อีก
Application.OnKey "~", "Macro1" รัน Macro1 เมื่อกดปุ่ม Enter
Application.OnKey "~" ยกเลิกการรันมาโครใดๆ สังเกตว่าไม่ต้องมี ,"" ข้างหลัง

ระวังว่า 2 ตัวอย่างหลังนั้น ถ้าใช้ {ENTER} จะหมายถึงปุ่ม ENTER บริเวณตัวเลข ส่วน ~ จะเป็นปุ่ม Enter บริเวณตัวอักษรครับ

สำหรับคำสั่งที่คอยตรวจว่ามีการทำงานกับชีทงาน ก็จะมี
Application.OnEntry, "Macro2" เมื่อมีการพิมพ์ข้อมูลในเซลใดๆ Macro2 จะทำงาน

หรือถ้าเข้าไปในหน้าที่ใช้เขียนโค้ด ในส่วนของ Worksheet ยังมี Private Sub ต่างๆ ที่เตรียมไว้ให้เราเพิ่มเติมโค้ดเข้าไปข้างใน เช่น

Private Sub Worksheet_Activate() เมื่อมีการไปที่ชีทอื่น แล้วคลิกกลับมาชีทนี้
Private Sub Worksheet_SelectionChange(ByVal Target As Range) เมื่อมีการเลื่อนไปยังเซลต่างๆ

ยังมีอีกหลายคำสั่งครับ ผมเองก็เคยใช้บางตัวเท่านั้น ยังต้องพึ่งท่านอื่นๆอยู่อีกมากครับ เดี๋ยวก็คงจะมาเพิ่มเติมให้อีก ระหว่างนี้ก็ให้ท่าน "galahut" ศึกษาที่ผมแนะนำนี้ไปพลางๆก่อน แล้วไอเดียดีๆอาจจะเกิดขึ้นเองครับผม

galahut
13 Jun 2007, 16:28
ผมทดลองนำคำแนะนำของคุณมิตรภาพไปศึกษาและลองเขียนดูให้เข้ากับที่ต้องการ
ปรากฎว่าได้ผลอย่างที่คิดในระดับนึงเลยครับ แต่ก็ได้ปัญหามาอีกระดับนึงเช่นกัน
ไม่รู้ว่าเพราะนำเอาไปใช้แบบไม่เข้าใจอย่างลึกซึ้งดีพอหรือเปล่า จึงขอรบกวนถาม
ปัญหาที่เกิดด้วยครับ
1) พอผมใช้คำสั่ง พอผมใช้คำสั่ง application.onkey "~" แล้ว เมื่อผมสร้าง sub ตัวใหม่ขึ้นมา
มันไม่สามารถรันมาโครได้ เป็นเพราะอะไรหรือครับ หรือมีคำสั่งไหนเพื่อยกเลิกคำสั่งapplication.onkey "~" นี้ไหมครับ
2) มีคำสั่งที่สามารถเช็คการ activate ของเซลไหมครับ ปรกติเคยใช้แต่การสั่งให้เซลนี้ เซลนั้น activate แต่ผมอยากรู้ว่าถ้าเราจะวางเงื่อนไขให้ตรวจสอบ เช่น ถ้าเซล...activate แล้วให้ดำเนินการ.... แบบนี้ต้องใช้คำสั่งแบบไหนหรือครับ เคยลองเขียนเป็น if cells().activate then กับ
if cells().attivate = true then แล้ว ไม่ได้ผลทั้งคู่เลยครับ (ทั้งสองอันนี้คิดเองนะครับเพราะไม่รู้จะหาที่ไหน)
3) ตอนนี้ผมใช้วิธี
Sub inputzone()
Cells(1, 1).Activate
Application.OnKey "~", "calculatezone"
End Sub
Sub calculatezone()
Cells(1, 3).Activate
Application.OnKey "~", "inputzone"
End Sub
เพื่อให้เซลที่ผมต้องการ activate แค่ 2 ช่องที่เป็นช่องรับข้อมูล มันมีวิธีที่ง่ายกว่านี้ไหมครับ
เพราะผมดูแล้วรู้สึกว่ามันยุ่งยากยังไงไม่รู้ครับ
ตอนนี้คิดว่าปัญหาที่ติดๆขัดๆมีเท่านี้ รบกวนด้วยนะครับ ขอบคุณสำหรับคำแนะนำ

มิตรภาพ
13 Jun 2007, 18:08
ผมได้ลองเขียนโค้ดเพื่อสร้างงานตามโจทย์ดูนะครับ ลองดูในไฟล์แนบครับผม


Sub Auto_Open()
Application.MoveAfterReturn = False
Range("a1").Select
ActiveSheet.OnEntry = "HourOfWork"
End Sub

Sub Auto_Close()
Application.MoveAfterReturn = True
End Sub

Sub HourOfWork()
If ActiveCell.Address(0, 0) = "A1" Then
Range("C1").Select
ElseIf ActiveCell.Address(0, 0) = "C1" Then
WriteHour
Range("A1,C1").ClearContents
Range("A1").Select
End If
End Sub

Sub WriteHour()
Dim aRow As Integer, aColumn As Integer
aRow = Columns("A").Find(Range("A1").Text, after:=Range("a12")).Row
aColumn = Rows(aRow).Find("", after:=Range("a" & aRow)).Column
Cells(aRow, aColumn).Formula = Range("c1").Text
End Sub

galahut
14 Jun 2007, 07:21
ผมได้ลองเขียนโค้ดเพื่อสร้างงานตามโจทย์ดูนะครับ ลองดูในไฟล์แนบครับผม
ขอรับไปเรียนรู้เลยนะครับ เพราะทดลองดูแล้วได้ผลตามที่ต้องการ แต่ว่าที่คุณมิตรภาพ
comment มาเป็นภาษาไทยของผมเปิดดูแล้วมันอ่านไม่ได้น่ะครับ เลยอาจจะยังไม่เข้าใจ
บางส่วน คงต้องทำความเข้าใจนานซักหน่อย ถ้ายังไงอาจจะต้องกลับมารบกวน
บางตัวที่ไม่เข้าใจอีกนะครับ ขอบคุณครับสำหรับคำแนะนำ

ปรับหน้าโค้ดให้อ่านไทยได้
- ที่เมนูในหน้าโค้ด ไปที่ Tools/Options
- เลือกแท็บ Editor Format
- เลือก Font เป็น Microsoft Sans Serif (Thai)
:)
ขอบคุณครับที่ชี้แนะ

มิตรภาพ
14 Jun 2007, 07:54
ปรับหน้าโค้ดให้อ่านไทยได้

- ที่เมนูในหน้าโค้ด ไปที่ Tools/Options
- เลือกแท็บ Editor Format
- เลือก Font เป็น Microsoft Sans Serif (Thai)

:)

jaroengd
14 Jun 2007, 15:34
สวัสดีครับ
ผมขอเสนออีกวิธึครับ โดยใช้วิธีรับข้อมูลด้วย Inputbox แล้วก็วนลูปจนกว่านะเสร็จงานทั้งหมด
สำหรับการเลื่อนไปยังเซลล์ที่ต้องการนั้น ใช้เซลล์ติดกันเป็นตัวรับข้อมูล ก็ไปเซ็ตได้เลยที่
Tools>Options>Edit
คลิก เลือก Move Selection after Enter ให้เลื่อนไปทางไหนก็ได้ครับ

:D

galahut
15 Jun 2007, 05:47
เรื่อง input box นั้น ในครั้งแรกที่ผมที่รับงานนี้มา ผมก็ทดลองใช้ครับ
แต่มันมีปัญหาเนื่องจากข้อมูลที่กรอกมีเยอะ ทำให้กรอกสับกันบ่อยๆ
แล้วต้องคอยออกจาก input box มาเพื่อแก้ค่าแล้วต้องกลับไปรันมาโคร
เพื่อเรียกinput boxขึ้นมาใหม่ ด้วยความยุ่งยากส่วนนึงตรงนี้
ทำให้ผมต้องหาวิธีที่ต้องการใหม่ครับ
พูดถึงเรื่องinput box ผมมีปัญหาอย่างนึงครับตอนใช้งาน คือพอใส่input box
ลงไปในloop แล้วผมออกจากinput box ไม่ได้ครับ(สงสัยloopจะดีเกินไป)
จึงขอเรียนถามหน่อยครับว่า ถ้าเรากดปุ่ม cancel หรือปิดinput boxที่ตัวกากบาท
ตัวแปรที่นำมารับค่าของinput boxจะมีค่าเป็นอะไรหรือครับ ตอนที่ผมใช้ผมต้องกำหนด
เงื่อนไขให้พิมพ์ว่า end ถึงออกได้ ลำบากเหลือเกินครับ รบกวนหน่อยนะครับ
สำหรับคำตอบ ขอบคุณครับ

Ubolwan
16 Jun 2007, 22:21
เรื่อง input box นั้น ในครั้งแรกที่ผมที่รับงานนี้มา ผมก็ทดลองใช้ครับ
พูดถึงเรื่องinput box ผมมีปัญหาอย่างนึงครับตอนใช้งาน คือพอใส่input box
ลงไปในloop แล้วผมออกจากinput box ไม่ได้ครับ (สงสัยloopจะดีเกินไป)
จึงขอเรียนถามหน่อยครับว่า ถ้าเรากดปุ่ม cancel หรือปิดinput box ที่ตัวกากบาท
ตัวแปรที่นำมารับค่าของinput boxจะมีค่าเป็นอะไรหรือครับ ตอนที่ผมใช้ผมต้องกำหนด
เงื่อนไขให้พิมพ์ว่า end ถึงออกได้ ลำบากเหลือเกินครับ รบกวนหน่อยนะครับ
สำหรับคำตอบ ขอบคุณครับ

ถามค่ะว่า Inputbox ที่คุณใช้เป็น Inputbox จาก VBA Built-in หรือ Inputbox จาก Application.Inputbox ค่ะ

ลองใช้ Step Running โดยวางเคอร์เซอร์ลงในมาโครแล้วกดแป้น F8
ไม่ต้องกรอกค่าใด ๆ ลงใน Inputbox โดยกดปุ่ม OK หรือ กากะบาท หรือกดปุ่ม Cancel
เลื่อนเมาส์ไปลอยเหนือตัวแปรแล้วดู Screentip ของค่าตัวแปรค่ะ

galahut
18 Jun 2007, 10:27
ลองใช้ Step Running โดยวางเคอร์เซอร์ลงในมาโครแล้วกดแป้น F8
ไม่ต้องกรอกค่าใด ๆ ลงใน Inputbox โดยกดปุ่ม OK หรือ กากะบาท หรือกดปุ่ม Cancel
เลื่อนเมาส์ไปลอยเหนือตัวแปรแล้วดู Screentip ของค่าตัวแปรค่ะ
ขอบคุณครับสำหรับคำแนะนำ อีกคำถามครับ เราสามารถพิมพ์เลข 00
โดยไม่ให้เป็น text ได้ไหมครับ ผมพิมพ์ 00 มันก็จะแสดงแค่ 0
ลองปรับformat ก็แล้ว ถ้าไม่เป็น text มันก็จะไม่สามารถแสดงได้
ไม่ทราบว่ามีวิธีการอื่นไหมครับ ที่ให้แสดงค่า 00 โดยยังเป็นตัวเลขอยู่

sudawant
20 Jun 2007, 12:40
ลองโค้ดต่อไปนี้แทนการใช้ VBA InputBox ค่ะ เพราะ VBA InputBox ไม่สามารถตรวจจับได้ว่า User Click Cancel หรือ Click OK โดยลืมกรอกข้อมูล


Sub ShowXLSInputBox()
Dim varInput As Variant
varInput = Application.InputBox ("Enter your Text")
If varInput = False Then
End
ElseIf VarInput ="" Then
Msgbox "You did't input anything",VbokOnly+vbInformation
Else
Msgbox "Your input is: " &varInput ,VbokOnly+vbInformation
End if


ทดสอบโดยลองคลิกปุ่ม Cancel หรือคลิก OK แบบไม่ใส่ค่าใด ๆ
แล้วเปลี่ยนจาก Application.InputBox เป็น Inputbox กระทำซ้ำโดยลองคลิกปุ่ม Cancel หรือคลิก OK แบบไม่ใส่ค่าใด ๆ

ส่วนการแสดงค่าเลข 0 นำในเซลล์ ลอง ใช้การ Format -> Cells.. --> Number --> Category -> Custom -> Type -> 000000
Click OK