วิธีหลีกเลี่ยงการใช้ Select ใน Excel VBA


537

ฉันได้ยินมามากเกี่ยวกับการใช้ความเกลียดชังที่เข้าใจยาก.Selectใน Excel VBA แต่ไม่แน่ใจว่าจะหลีกเลี่ยงการใช้งานได้อย่างไร ฉันพบว่ารหัสของฉันจะสามารถใช้งานได้อีกถ้าฉันสามารถใช้ตัวแปรแทนSelectฟังก์ชั่น แต่ผมไม่แน่ใจว่าวิธีการที่จะอ้างถึงสิ่งที่ (เช่นActiveCellฯลฯ ) Selectถ้าไม่ได้ใช้

ฉันได้พบบทความนี้ในช่วงและตัวอย่างนี้เกี่ยวกับประโยชน์ของการไม่ใช้เลือกแต่ไม่สามารถหาอะไรในวิธี ?


14
สิ่งสำคัญที่ควรทราบคือมีอินสแตนซ์เมื่อใช้Selectและ / หรือActiveSheetอื่น ๆ เป็นต้นไม่สามารถหลีกเลี่ยงได้อย่างสมบูรณ์ นี่คือตัวอย่างที่ฉันพบ: stackoverflow.com/questions/22796286/…
Rick รองรับโมนิก้า

9
และมีโอกาส - แก้ไขข้อมูลแผนภูมิใน ppt โดยมีไฟล์ excel เป็นหนึ่ง - ซึ่งจำเป็นต้องมีการเปิดใช้งานหรือเลือก
brettdj

@brettdj - นี่เป็นตัวอย่างล่าสุด เมื่อต้องการตั้งค่าแผ่นงานทั้งหมดในเวิร์กบุ๊กเป็นค่าเดียวกันดูเหมือนว่า.Select / .Selectionจำเป็นต้องมี
BruceWayne

3
@bruce จาก QA เดียวกันดูเหมือนว่าไม่ใช่
chris neilsen

คำตอบ:


565

ตัวอย่างของวิธีหลีกเลี่ยงการเลือก

ใช้Dimตัวแปร 'd

Dim rng as Range

Setตัวแปรเป็นช่วงที่ต้องการ มีหลายวิธีในการอ้างถึงช่วงเซลล์เดียว

Set rng = Range("A1")
Set rng = Cells(1,1)
Set rng = Range("NamedRange")

หรือช่วงหลายเซลล์

Set rng = Range("A1:B10")
Set rng = Range("A1", "B10")
Set rng = Range(Cells(1,1), Cells(10,2))
Set rng = Range("AnotherNamedRange")
Set rng = Range("A1").Resize(10,2)

คุณสามารถใช้ทางลัดไปยังEvaluateวิธีการได้ แต่วิธีนี้มีประสิทธิภาพน้อยกว่าและควรหลีกเลี่ยงในรหัสการผลิต

Set rng = [A1]
Set rng = [A1:B10]

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

Dim ws As Worksheet
Set ws = Worksheets("Sheet1")
Set rng = ws.Cells(1,1)
With ws
    Set rng = .Range(.Cells(1,1), .Cells(2,10))
End With

หากคุณไม่ต้องการที่จะทำงานร่วมกับActiveSheetเพื่อความชัดเจนดีที่สุดที่จะมีความชัดเจน แต่ระวังบางWorksheetวิธีเปลี่ยนแผ่นงานที่ใช้งานอยู่

Set rng = ActiveSheet.Range("A1")

อีกครั้งนี่หมายถึงสมุดงานที่ใช้งานอยู่ ยกเว้นว่าคุณต้องการทำงานเฉพาะกับActiveWorkbookหรือThisWorkbookโดยเฉพาะจะเป็นการดีกว่าที่จะหรี่Workbookตัวแปรเช่นกัน

Dim wb As Workbook
Set wb = Application.Workbooks("Book1")
Set rng = wb.Worksheets("Sheet1").Range("A1")

หากคุณไม่ต้องการที่จะทำงานร่วมกับActiveWorkbookเพื่อความชัดเจนดีที่สุดที่จะมีความชัดเจน แต่ระวังWorkBookวิธีการต่าง ๆเปลี่ยนหนังสือที่ใช้งานอยู่

Set rng = ActiveWorkbook.Worksheets("Sheet1").Range("A1")

คุณยังสามารถใช้ThisWorkbookวัตถุเพื่ออ้างถึงหนังสือที่มีรหัสที่ใช้

Set rng = ThisWorkbook.Worksheets("Sheet1").Range("A1")

รหัสทั่วไปที่ไม่ดีคือการเปิดหนังสือรับข้อมูลบางส่วนแล้วปิดอีกครั้ง

นี้ไม่ดี:

Sub foo()
    Dim v as Variant
    Workbooks("Book1.xlsx").Sheets(1).Range("A1").Clear
    Workbooks.Open("C:\Path\To\SomeClosedBook.xlsx")
    v = ActiveWorkbook.Sheets(1).Range("A1").Value
    Workbooks("SomeAlreadyOpenBook.xlsx").Activate
    ActiveWorkbook.Sheets("SomeSheet").Range("A1").Value = v
    Workbooks(2).Activate
    ActiveWorkbook.Close()
End Sub

และจะดีกว่าเช่น:

Sub foo()
    Dim v as Variant
    Dim wb1 as Workbook
    Dim  wb2 as Workbook
    Set wb1 = Workbooks("SomeAlreadyOpenBook.xlsx")
    Set wb2 = Workbooks.Open("C:\Path\To\SomeClosedBook.xlsx")
    v = wb2.Sheets("SomeSheet").Range("A1").Value
    wb1.Sheets("SomeOtherSheet").Range("A1").Value = v
    wb2.Close()
End Sub

ส่งช่วงไปยังSubs และFunctions ของคุณเป็นตัวแปรช่วง

Sub ClearRange(r as Range)
    r.ClearContents
    '....
End Sub

Sub MyMacro()
    Dim rng as Range
    Set rng = ThisWorkbook.Worksheets("SomeSheet").Range("A1:B10")
    ClearRange rng
End Sub

คุณควรใช้วิธีการ (เช่นFindและCopy) กับตัวแปร

Dim rng1 As Range
Dim rng2 As Range
Set rng1 = ThisWorkbook.Worksheets("SomeSheet").Range("A1:A10")
Set rng2 = ThisWorkbook.Worksheets("SomeSheet").Range("B1:B10")
rng1.Copy rng2

หากคุณวนลูปในช่วงของเซลล์มักจะดีกว่า (เร็วกว่า) เพื่อคัดลอกค่าช่วงไปยังอาเรย์ตัวแปรชุดแรกและวนลูปมากกว่านั้น

Dim dat As Variant
Dim rng As Range
Dim i As Long

Set rng = ThisWorkbook.Worksheets("SomeSheet").Range("A1:A10000")
dat = rng.Value  ' dat is now array (1 to 10000, 1 to 1)
for i = LBound(dat, 1) to UBound(dat, 1)
    dat(i,1) = dat(i,1) * 10 'or whatever operation you need to perform
next
rng.Value = dat ' put new values back on sheet

นี่เป็นนักชิมเล็ก ๆ สำหรับสิ่งที่เป็นไปได้


7
เพิ่มคำตอบที่ยอดเยี่ยมนี้เพื่อที่จะทำงานในช่วงที่คุณไม่จำเป็นต้องรู้ขนาดที่แท้จริงของมันตราบใดที่คุณรู้ว่าด้านซ้ายบน ... เช่นrng1(12, 12)จะทำงานแม้ว่า rng1 ถูกตั้งค่าเป็น[A1:A10]เพียง
MikeD

3
@chrisneilsen คริสผมเชื่อว่าคุณยังสามารถใช้แผ่นคำนำหน้าก่อนโน้ตอ้างอิงเซลล์ชวเลขจะช่วยให้คุณประหยัดจากการพิมพ์Rangeเช่นนี้หรือActiveSheet.[a1:a4] ws.[b6]
Logan Reed

3
@AndrewWillems ... หรือ48ครั้งในโพสต์นี้ แต่ใครกำลังนับ ☺ ... แต่อย่างจริงจังมันง่ายที่จะลืมเมื่อทำงานกับตัวแปรที่เก็บวัตถุ variantตัวแปรไม่จำเป็นต้องSet จนกว่าคุณกำหนดวัตถุที่จะมัน ตัวอย่างเช่นDim x: x = 1ไม่เป็นไร แต่Dim x: x = Sheets("Sheet1")จะสร้างข้อผิดพลาด 438 อย่างไรก็ตามเพียงเพื่อสร้างความสับสน / ชี้แจงDim x: x = Range("A1")จะไม่สร้างข้อผิดพลาด ทำไม? ... เพราะมันมอบหมายมูลค่าของวัตถุให้กับตัวแปรที่ไม่ได้มีการอ้างอิงถึงวัตถุเอง (เพราะมันเทียบเท่าDim x: x = Range("A1").Value)
ashleedawg

1
@ user3932000 ฉันไม่ทราบถึงสถานการณ์ที่แผ่นงานเปลี่ยนโดยอัตโนมัติ สำหรับชื่อไฟล์มันจะทำก็ต่อเมื่อมีไฟล์ชื่อนั้นอยู่ในโฟลเดอร์แล้ว เพียงใช้บันทึก ... หรือรหัสฮาร์ดโค้ดเพื่อบันทึกเป็นสตริง หากคุณไม่สามารถแก้ปัญหานี้ได้คุณควรถามคำถามแยกต่างหากเกี่ยวกับปัญหาแทนที่จะแสดงความคิดเห็น
TylerH

1
@ user3932000 ที่จะทำให้น่าสนใจ Q. ฉันแน่ใจว่ามีวิธีการจัดการกับ .. คุณได้รับในนานพอที่จะรู้ว่าการหักหลังหัวข้อความคิดเห็นเกี่ยวกับ Q เก่าไม่ได้เป็นวิธีที่จะไป
chris neilsen

212

สองเหตุผลหลักที่ควรหลีกเลี่ยง.Select/ .Activate/ Selection/ Activecell/ Activesheet/ Activeworkbookฯลฯ ...

  1. มันทำให้โค้ดของคุณช้าลง
  2. มักเป็นสาเหตุหลักของข้อผิดพลาดรันไทม์

เราจะหลีกเลี่ยงได้อย่างไร

1)ทำงานโดยตรงกับวัตถุที่เกี่ยวข้อง

พิจารณารหัสนี้

Sheets("Sheet1").Activate
Range("A1").Select
Selection.Value = "Blah"
Selection.NumberFormat = "@"

รหัสนี้สามารถเขียนเป็น

With Sheets("Sheet1").Range("A1")
    .Value = "Blah"
    .NumberFormat = "@"
End With

2)หากจำเป็นต้องประกาศตัวแปรของคุณ รหัสเดียวกันข้างต้นสามารถเขียนได้เป็น

Dim ws as worksheet

Set ws = Sheets("Sheet1")

With ws.Range("A1")
    .Value = "Blah"
    .NumberFormat = "@"
End With

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

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

7
ฉันคิดว่าประเด็นคือไม่ควรหลีกเลี่ยงการใช้สิ่งเหล่านั้นอย่างสมบูรณ์ แต่ให้มากที่สุด ถ้าคุณต้องการบันทึกเวิร์กบุ๊กดังนั้นเมื่อมีคนเปิดมันเซลล์บางเซลล์ในแผ่นงานบางแผ่นจะถูกเลือกคุณจะต้องเลือกแผ่นงานและเซลล์นั้น คัดลอก / วางเป็นตัวอย่างที่ไม่ดีอย่างน้อยในกรณีของค่าสามารถทำได้เร็วขึ้นด้วยรหัสเช่นSheets(2).[C10:D12].Value = Sheets(1).[A1:B3].Value
robotik

1
@Nick คุณไม่จำเป็นต้องเปิดใช้งานชีตเพื่อวางลงในแผ่นกรองหรือกรอง ใช้วัตถุแผ่นงานในคำสั่งวางหรือตัวกรองของคุณ มันจะง่ายขึ้นเมื่อคุณเรียนรู้รูปแบบวัตถุ Excel ผ่านการฝึกฝน ฉันเชื่อว่ามีเพียงครั้งเดียวที่ฉันใช้งานการเปิดใช้งานคือเมื่อฉันสร้างแผ่นงานใหม่ แต่ฉันต้องการให้แผ่นงานต้นฉบับปรากฏขึ้นเมื่อทำรหัสเสร็จ
phrebh

3
@phrebh คุณไม่จำเป็นต้องใช้.Activateเพื่อย้ายไปยังแผ่นงานต้นฉบับเพียงใช้Application.Goto
GMalc

88

จุดเล็ก ๆ แห่งการเน้นฉันจะเพิ่มคำตอบที่ยอดเยี่ยมทั้งหมดที่ได้รับข้างต้น:

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

ต่อไปนี้เป็นเหตุผลเพิ่มเติมสองสามข้อในการใช้ช่วงที่ตั้งชื่ออย่างเสรีแม้ว่าฉันแน่ใจว่าฉันจะนึกถึงอีก

ช่วงที่มีชื่อทำให้รหัสของคุณง่ายต่อการอ่านและทำความเข้าใจ

ตัวอย่าง:

Dim Months As Range
Dim MonthlySales As Range

Set Months = Range("Months")
'e.g, "Months" might be a named range referring to A1:A12

Set MonthlySales = Range("MonthlySales")
'e.g, "Monthly Sales" might be a named range referring to B1:B12

Dim Month As Range
For Each Month in Months
    Debug.Print MonthlySales(Month.Row)
Next Month

มันค่อนข้างชัดเจนว่าช่วงที่มีชื่อMonthsและMonthlySalesมีและกระบวนการทำอะไร

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

ช่วงที่มีชื่อช่วยให้มั่นใจว่าแมโครของคุณจะไม่แตกเมื่อ (ไม่ใช่ถ้า!) การกำหนดค่าของสเปรดชีตเปลี่ยนไป

พิจารณาหากตัวอย่างด้านบนเขียนเป็นแบบนี้:

Dim rng1 As Range
Dim rng2 As Range

Set rng1 = Range("A1:A12")
Set rng2 = Range("B1:B12")

Dim rng3 As Range
For Each rng3 in rng1 
    Debug.Print rng2(rng3.Row)
Next rng3

รหัสนี้จะทำงานได้ดีในตอนแรก - จนกว่าคุณหรือผู้ใช้ในอนาคตจะตัดสินใจ "gee wiz ฉันคิดว่าฉันจะเพิ่มคอลัมน์ใหม่กับปีในคอลัมน์A!" หรือใส่คอลัมน์ค่าใช้จ่ายระหว่างเดือนและ คอลัมน์การขายหรือเพิ่มส่วนหัวในแต่ละคอลัมน์ ตอนนี้รหัสของคุณเสีย และเนื่องจากคุณใช้ชื่อตัวแปรที่แย่มากมันจะทำให้คุณมีเวลามากขึ้นในการหาวิธีแก้ไขมันเกินกว่าที่ควรจะเป็น

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


6
การถกเถียงกันว่าการออกแบบสเปรดชีตที่ดีหรือไม่ดีนั้นดำเนินต่อไปหรือไม่ จากประสบการณ์ของฉันพวกเขาเพิ่มข้อผิดพลาด (สำหรับผู้ใช้มาตรฐานที่ไม่ต้องการรหัส)
brettdj


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

8
ไม่มีการอภิปรายที่มีความหมาย ทุกคนที่โต้แย้งชื่อที่กำหนดไม่ได้ใช้เวลาในการทำความเข้าใจการแยกสาขา สูตรที่มีชื่ออาจเป็นโครงสร้างที่ลึกซึ้งและมีประโยชน์ที่สุดใน Excel ทั้งหมด
ฮีโร่ Excel

10
@brettdj: การอ้างอิงของคุณถูกต้อง แต่คุณลืมที่จะพูดถึงว่ามันจะตามด้วยวลี "ยกเว้น ... " หกคำ หนึ่งในนั้นคือ: " ยกเว้นเป็นการทดแทนการอ้างอิงเซลล์ในการเข้ารหัสแมโคร ใช้ชื่อ Excel เสมอเพื่อทดแทนการอ้างอิงเซลล์เมื่อสร้างแมโครนี่คือการหลีกเลี่ยงข้อผิดพลาดที่เกิดขึ้นจากการแทรกแถวหรือคอลัมน์เพิ่มเติมโดยที่การเข้ารหัสแมโครไม่ ชี้ไปยังแหล่งข้อมูลที่ต้องการ "
Marcus Mangelsdorf

47

ฉันจะให้คำตอบสั้น ๆ เพราะทุกคนให้คำตอบยาว ๆ

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

ดังนั้นคุณสามารถกำจัดปัญหาเหล่านี้ได้โดยอ้างอิงเซลล์ของคุณโดยตรง ซึ่งไป:

'create and set a range
Dim Rng As Excel.Range
Set Rng = Workbooks("Book1").Worksheets("Sheet1").Range("A1")
'OR
Set Rng = Workbooks(1).Worksheets(1).Cells(1, 1)

หรือคุณสามารถ

'Just deal with the cell directly rather than creating a range
'I want to put the string "Hello" in Range A1 of sheet 1
Workbooks("Book1").Worksheets("Sheet1").Range("A1").value = "Hello"
'OR
Workbooks(1).Worksheets(1).Cells(1, 1).value = "Hello"

มีหลายวิธีรวมกัน แต่นั่นเป็นความคิดทั่วไปที่แสดงออกโดยเร็วที่สุดสำหรับคนที่ใจร้อนอย่างฉัน


33

"... และฉันพบว่ารหัสของฉันจะสามารถใช้งานได้อีกครั้งถ้าฉันสามารถใช้ตัวแปรแทนฟังก์ชั่น Select"

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

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

ตัวอย่างของกรอบย่อยตามการเลือก:

Public Sub Run_on_Selected()
    Dim rng As Range, rSEL As Range
    Set rSEL = Selection    'store the current selection in case it changes
    For Each rng In rSEL
        Debug.Print rng.Address(0, 0)
        'cell-by-cell operational code here
    Next rng
    Set rSEL = Nothing
End Sub

Public Sub Run_on_Selected_Visible()
    'this is better for selected ranges on filtered data or containing hidden rows/columns
    Dim rng As Range, rSEL As Range
    Set rSEL = Selection    'store the current selection in case it changes
    For Each rng In rSEL.SpecialCells(xlCellTypeVisible)
        Debug.Print rng.Address(0, 0)
        'cell-by-cell operational code here
    Next rng
    Set rSEL = Nothing
End Sub

Public Sub Run_on_Discontiguous_Area()
    'this is better for selected ranges of discontiguous areas
    Dim ara As Range, rng As Range, rSEL As Range
    Set rSEL = Selection    'store the current selection in case it changes
    For Each ara In rSEL.Areas
        Debug.Print ara.Address(0, 0)
        'cell group operational code here
        For Each rng In ara.Areas
            Debug.Print rng.Address(0, 0)
            'cell-by-cell operational code here
        Next rng
    Next ara
    Set rSEL = Nothing
End Sub

โค้ดจริงในการประมวลผลอาจเป็นอะไรก็ได้จากบรรทัดเดียวไปยังหลายโมดูล ฉันใช้วิธีนี้ในการเริ่มต้นรูทีนที่ใช้เวลานานในการเลือกเซลล์ที่มีชื่อไฟล์ของสมุดงานภายนอกที่ขรุขระ

ในระยะสั้นไม่ทิ้งSelectionเนื่องจากความสัมพันธ์ใกล้ชิดกับและ.Select ActiveCellในฐานะที่เป็นคุณสมบัติแผ่นงานมันมีวัตถุประสงค์อื่น ๆ อีกมากมาย

(ใช่ฉันรู้ว่าคำถามนี้เกี่ยวกับ.Selectไม่ใช่Selectionแต่ฉันต้องการลบความเข้าใจผิดใด ๆ ที่ coders VBA มือใหม่อาจอนุมานได้)


13
SelectionRangeสามารถเป็นอะไรก็ได้ในแผ่นนั้นอาจทดสอบกันครั้งแรกชนิดของวัตถุก่อนที่จะกำหนดให้กับตัวแปรตั้งแต่คุณประกาศอย่างชัดเจนว่ามันเป็น
L42

29

โปรดทราบว่าในสิ่งต่อไปนี้ฉันกำลังเปรียบเทียบวิธีเลือก (วิธีที่ OP ต้องการหลีกเลี่ยง) กับแนวทาง Range (และนี่คือคำตอบของคำถาม) ดังนั้นอย่าหยุดอ่านเมื่อคุณเห็นตัวเลือกแรก

มันขึ้นอยู่กับสิ่งที่คุณพยายามทำจริงๆ อย่างไรก็ตามตัวอย่างง่ายๆอาจมีประโยชน์ สมมติว่าคุณต้องการตั้งค่าเซลล์ที่ใช้งานเป็น "foo" ใช้ ActiveCell คุณจะเขียนดังนี้:

Sub Macro1()
    ActiveCell.Value = "foo"
End Sub

หากคุณต้องการใช้สำหรับเซลล์ที่ไม่ได้ใช้งานอยู่เช่นสำหรับ "B2" คุณควรเลือกก่อนเช่นนี้:

Sub Macro2()
    Range("B2").Select
    Macro1
End Sub

การใช้ช่วงคุณสามารถเขียนมาโครทั่วไปที่สามารถใช้เพื่อตั้งค่าของเซลล์ใด ๆ ที่คุณต้องการในสิ่งที่คุณต้องการ:

Sub SetValue(cellAddress As String, aVal As Variant)
    Range(cellAddress).Value = aVal
End Sub

จากนั้นคุณสามารถเขียน Macro2 ใหม่เป็น:

Sub Macro2()
    SetCellValue "B2", "foo"
End Sub

และ Macro1 เป็น:

Sub Macro1()
    SetValue ActiveCell.Address, "foo"
End Sub

หวังว่านี่จะช่วยให้ชัดเจนขึ้น


1
ขอบคุณสำหรับการตอบสนองที่ยอดเยี่ยมอย่างรวดเร็ว นั่นหมายความว่าถ้าโดยปกติฉันจะเพิ่มเซลล์ลงในช่วงตั้งชื่อช่วงและวนซ้ำมันฉันควรข้ามไปที่การสร้างอาร์เรย์หรือไม่
BiGXERO

ฉันไม่แน่ใจว่าฉันเข้าใจสิ่งที่คุณหมายถึง แต่คุณสามารถสร้างช่วงที่มีคำสั่งเดียว (เช่นช่วง ("B5: C14")) และคุณสามารถตั้งค่าได้ในครั้งเดียว (ถ้ามันจะต้องเหมือนกันสำหรับ ทุกเซลล์ในช่วง) เช่น Range ("B5: C14") Value = "abc"
Francesco Baruchelli

29

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

นี่คือวิธีที่คุณอาจหลีกเลี่ยงSelectและActivateในกรณีต่อไปนี้:


การเพิ่มแผ่นงานใหม่และคัดลอกเซลล์บน:

จาก (รหัสที่สร้างด้วยตัวบันทึกแมโคร):

Sub Makro2()
    Range("B2").Select
    Sheets.Add After:=ActiveSheet
    Sheets("Tabelle1").Select
    Sheets("Tabelle1").Name = "NewName"
    ActiveCell.FormulaR1C1 = "12"
    Range("B2").Select
    Selection.Copy
    Range("B3").Select
    ActiveSheet.Paste
    Application.CutCopyMode = False
End Sub

ถึง:

Sub TestMe()
    Dim ws As Worksheet
    Set ws = Worksheets.Add
    With ws
        .Name = "NewName"
        .Range("B2") = 12
        .Range("B2").Copy Destination:=.Range("B3")
    End With
End Sub

เมื่อคุณต้องการคัดลอกช่วงระหว่างแผ่นงาน:

จาก:

Sheets("Source").Select
Columns("A:D").Select
Selection.Copy
Sheets("Target").Select
Columns("A:D").Select
ActiveSheet.Paste

ถึง:

Worksheets("Source").Columns("A:D").Copy Destination:=Worksheets("Target").Range("a1")

ใช้ช่วงชื่อแฟนซี

คุณสามารถเข้าถึงได้ด้วย[]ซึ่งมีความสวยงามมากเมื่อเทียบกับวิธีอื่น ตรวจสอบตัวเอง:

Dim Months As Range
Dim MonthlySales As Range

Set Months = Range("Months")    
Set MonthlySales = Range("MonthlySales")

Set Months =[Months]
Set MonthlySales = [MonthlySales]

ตัวอย่างจากด้านบนจะเป็นดังนี้:

Worksheets("Source").Columns("A:D").Copy Destination:=Worksheets("Target").[A1]

ไม่ใช่การคัดลอกค่า แต่รับค่า

โดยปกติถ้าคุณยินดีที่selectคุณอาจคัดลอกบางสิ่งบางอย่าง หากคุณสนใจเฉพาะค่านี่เป็นตัวเลือกที่ดีเพื่อหลีกเลี่ยงการเลือก:

Range("B1:B6").Value = Range("A1:A6").Value


ลองอ้างอิงแผ่นงานเสมอ

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

'This will work only if the 2. Worksheet is selected!
Public Sub TestMe()
    Dim rng As Range
    Set rng = Worksheets(2).Range(Cells(1, 1), Cells(2, 2)).Copy
End Sub

'This works always!
Public Sub TestMe2()
    Dim rng As Range
    With Worksheets(2)
        .Range(.Cells(1, 1), .Cells(2, 2)).Copy
    End With
End Sub

ฉันไม่เคยใช้.Selectหรือ.Activateเพื่ออะไรเลยจริงๆ?

  • ตัวอย่างที่ดีของเวลาที่คุณจะได้รับการพิสูจน์ในการใช้งาน.Activateและ.Selectเมื่อคุณต้องการให้แน่ใจว่ามีการเลือกเวิร์กชีทเฉพาะด้วยเหตุผลด้านภาพ เช่น Excel ของคุณจะเปิดด้วยแผ่นงานใบปะหน้าที่เลือกไว้ก่อนโดยไม่สนใจว่าไฟล์ใดที่เป็น ActiveSheet เมื่อไฟล์ถูกปิด

ดังนั้นบางอย่างเช่นโค้ดด้านล่างจึงใช้ได้จริง ๆ :

Private Sub Workbook_Open()
    Worksheets("Cover").Activate
End Sub

คุณสามารถใช้ Application.Goto แทน Worksheets.Activate ค่อนข้างมีความเสี่ยงน้อยกว่า
Geoff Griswald

1
FYI ตอบล่าช้า - เป็นตัวอย่างที่ดีและไม่คาดคิดสำหรับสิ่งที่จำเป็น.Select- รวมถึงการทำงานของฉัน - สามารถดูได้ที่ วิธีการเขียนข้อมูลที่เหมือนกันในแผ่นงานทั้งหมด - @Vityata :)
TM

1
@TM - เป็นตัวอย่างที่น่าสนใจและอาจบันทึกเป็นมิลลิวินาทีสำหรับแผ่นงานมากกว่า 100 แผ่นแต่ฉันอาจไม่แนะนำถ้าฉันเห็นที่ใดที่หนึ่ง อย่างไรก็ตามการเลือกไม่มีการเขียนอย่างชัดเจน แต่เป็นผลมาจาก.FillAcrossSheetsนี้จึงเป็นที่ในระหว่าง (อย่างน้อยในความคิดของฉันเกี่ยวกับอนุกรมวิธาน VBA)
Vityata

17

ระบุเวิร์กบุ๊กแผ่นงานและเซลล์ / ช่วงเสมอ

ตัวอย่างเช่น:

Thisworkbook.Worksheets("fred").cells(1,1)
Workbooks("bob").Worksheets("fred").cells(1,1)

เนื่องจากผู้ใช้จะคลิกปุ่มเสมอและทันทีที่การย้ายโฟกัสออกจากเวิร์กบุ๊กรหัสต้องการทำงานด้วยดังนั้นสิ่งต่าง ๆ จึงผิดปกติอย่างสมบูรณ์

และไม่เคยใช้ดัชนีของสมุดงาน

Workbooks(1).Worksheets("fred").cells(1,1)

คุณไม่ทราบว่าเวิร์กบุ๊กอื่นจะเปิดเมื่อผู้ใช้เรียกใช้รหัสของคุณ


7
ชื่อของเวิร์กชีทก็สามารถเปลี่ยนแปลงได้เช่นกัน ใช้ชื่อรหัสแทน
Rick สนับสนุนโมนิก้า

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

10

วิธีการเหล่านี้ค่อนข้างน่าอับอายดังนั้นการเป็นผู้นำของ @Vityata และ @Jeeped เพื่อประโยชน์ในการวาดเส้นในทราย:

ทำไมไม่โทร.Activate, .Select, Selection, ActiveSomethingวิธีการ / คุณสมบัติ

โดยพื้นฐานแล้วพวกเขาถูกเรียกมาเพื่อจัดการกับการป้อนข้อมูลของผู้ใช้เป็นหลักผ่าน Application UI เนื่องจากเป็นวิธีการที่เรียกว่าเมื่อผู้ใช้จัดการวัตถุผ่าน UI จึงเป็นวิธีที่บันทึกโดยตัวบันทึกแมโครและนั่นคือสาเหตุที่การเรียกพวกมันนั้นเปราะหรือซ้ำซ้อนสำหรับสถานการณ์ส่วนใหญ่: คุณไม่จำเป็นต้องเลือก วัตถุเพื่อดำเนินการกับSelectionขวาหลังจากนั้น

อย่างไรก็ตามคำจำกัดความนี้ตัดสินสถานการณ์ที่พวกเขาถูกเรียก:

เมื่อมีการโทร.Activate, .Select, .Selection, .ActiveSomethingวิธีการ / คุณสมบัติ

โดยทั่วไปเมื่อคุณคาดหวังให้ผู้ใช้ขั้นสุดท้ายมีบทบาทในการดำเนินการ

หากคุณมีการพัฒนาและคาดว่าผู้ใช้สามารถเลือกกรณีวัตถุสำหรับรหัสของคุณที่จะจับแล้ว.Selectionหรือ.ActiveObjectมี apropriate

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


6

การใช้ IMHO .selectมาจากคนที่ชอบฉันเริ่มเรียนรู้ VBA โดยความจำเป็นผ่านการบันทึกมาโครแล้วปรับเปลี่ยนรหัสโดยไม่ทราบว่า.selectต่อมาselectionเป็นเพียงคนกลางที่ไม่จำเป็น

.select สามารถหลีกเลี่ยงได้หลายโพสต์แล้วโดยการทำงานโดยตรงกับวัตถุที่มีอยู่แล้วซึ่งช่วยให้การอ้างอิงทางอ้อมต่างๆเช่นการคำนวณฉันและเจในทางที่ซับซ้อนและจากนั้นแก้ไขเซลล์ (i, j) ฯลฯ

มิฉะนั้นจะไม่มีอะไรผิดปกติกับ.selectตัวเองและคุณสามารถค้นหาการใช้งานนี้ได้อย่างง่ายดายเช่นฉันมีสเปรดชีตที่ฉันเติมด้วยวันที่เปิดใช้งานแมโครที่ใช้เวทย์มนตร์บางอย่างและส่งออกในรูปแบบที่ยอมรับได้ในแผ่นแยกต่างหาก อย่างไรก็ตามต้องใช้อินพุตสุดท้าย (คาดเดาไม่ได้) ในเซลล์ที่อยู่ติดกัน ดังนั้นที่นี่มาถึงช่วงเวลา.selectที่ช่วยฉันในการเคลื่อนไหวของเมาส์และคลิกเพิ่มเติม


2
ในขณะที่คุณพูดถูกมีอย่างน้อยหนึ่งอย่างผิดปกติกับการเลือก: มันช้า ช้ามากเมื่อเทียบกับทุกอย่างที่เกิดขึ้นในแมโคร
vacip

4

คำตอบที่รวดเร็ว:

เพื่อหลีกเลี่ยงการใช้.Selectวิธีการคุณสามารถตั้งค่าตัวแปรให้เท่ากับคุณสมบัติที่คุณต้องการ

►ตัวอย่างเช่นหากคุณต้องการค่าในCell A1คุณสามารถตั้งค่าตัวแปรให้เท่ากับคุณสมบัติค่าของเซลล์นั้น

  • ตัวอย่าง valOne = Range("A1").Value

►ตัวอย่างเช่นหากคุณต้องการชื่อรหัสของ 'Sheet3' คุณสามารถตั้งค่าตัวแปรให้เท่ากับคุณสมบัติชื่อรหัสของแผ่นงานนั้น

  • ตัวอย่าง valTwo = Sheets("Sheet3").Codename

ฉันหวังว่าจะช่วย แจ้งให้เราทราบหากคุณมีคำถามใด ๆ


3

ฉันสังเกตเห็นว่าไม่มีคำตอบใด ๆ ที่กล่าวถึงคุณสมบัติ . Offset นอกจากนี้ยังสามารถใช้เพื่อหลีกเลี่ยงการใช้การSelectกระทำเมื่อจัดการเซลล์บางอย่างโดยเฉพาะอย่างยิ่งในการอ้างอิงถึงเซลล์ที่เลือก (ตามที่ OP กล่าวถึงด้วยActiveCell)

นี่คือตัวอย่างสองสามอย่าง

ฉันยังจะถือว่า "ActiveCell" เป็นJ4

ActiveCell.Offset(2, 0).Value = 12

  • สิ่งนี้จะเปลี่ยนเซลล์J6ให้เป็นค่า 12
  • เครื่องหมายลบ -2 จะอ้างอิง J2

ActiveCell.Offset(0,1).Copy ActiveCell.Offset(,2)

  • นี้จะคัดลอกเซลล์ในการk4L4
  • โปรดทราบว่าไม่จำเป็นต้องใช้ "0" ในพารามิเตอร์ offset หากไม่ต้องการ (, 2)
  • คล้ายกับตัวอย่างก่อนหน้าลบ 1 จะเป็น i4

ActiveCell.Offset(, -1).EntireColumn.ClearContents

  • นี่จะล้างค่าในเซลล์ทั้งหมดในคอลัมน์ k

สิ่งเหล่านี้ไม่ได้บอกว่ามันเป็น "ดีกว่า" มากกว่าตัวเลือกด้านบน แต่เป็นเพียงรายการทางเลือก


0

การทำงานกับคุณสมบัติ. Parent ตัวอย่างนี้แสดงวิธีการตั้งค่าการอ้างอิง myRng เพียงครั้งเดียวที่เปิดใช้งานการเข้าถึงสภาพแวดล้อมทั้งหมดแบบไดนามิกโดยไม่ต้องเลือก, .Activate, .Activecell, .ActiveWorkbook, .ActiveSheet และอื่น ๆ (ไม่มีคุณสมบัติแบบเด็กธรรมดา)

Sub ShowParents()
    Dim myRng As Range
    Set myRng = ActiveCell
    Debug.Print myRng.Address                    ' an address of the selected cell
    Debug.Print myRng.Parent.name                ' the name of sheet, where MyRng is in
    Debug.Print myRng.Parent.Parent.name         ' the name of workbook, where MyRng is in
    Debug.Print myRng.Parent.Parent.Parent.name  ' the name of application, where MyRng is in

    ' You may use this feature to set reference to these objects
    Dim mySh    As Worksheet
    Dim myWbk   As Workbook
    Dim myApp   As Application

    Set mySh = myRng.Parent
    Set myWbk = myRng.Parent.Parent
    Set myApp = myRng.Parent.Parent.Parent
    Debug.Print mySh.name, mySh.Cells(10, 1).Value
    Debug.Print myWbk.name, myWbk.Sheets.Count
    Debug.Print myApp.name, myApp.Workbooks.Count

    ' You may use dynamically addressing
    With myRng
        .Copy

       ' pastes in D1 on sheet 2 in the same workbook, where copied cell is
        .Parent.Parent.Sheets(2).Range("D1").PasteSpecial xlValues
    ' or myWbk.Sheets(2).Range("D1").PasteSpecial xlValues

       ' we may dynamically call active application too
        .Parent.Parent.Parent.CutCopyMode = False
    ' or myApp.CutCopyMode = False
    End With
End Sub

ดีมาก แต่ไม่แน่ใจว่าสิ่งนี้เกี่ยวข้องกับคำถาม OPs หรือไม่ คุณไม่จำเป็นต้องมี "ผู้ปกครอง" เลยเพื่อทำงานใน VBA โดยไม่ต้องใช้ Select หรือ ActiveSheet
Geoff Griswald

0

เหตุผลหลักที่ไม่เคยใช้ Select หรือ Activesheet เป็นเพราะคนส่วนใหญ่จะเปิดเวิร์กบุ๊กอีกสองสามครั้ง (บางครั้งก็นับสิบ) เมื่อพวกเขาเรียกใช้แมโครของคุณและถ้าพวกเขาคลิกมาจากแผ่นงานของคุณในขณะที่แมโครของคุณทำงาน หนังสือที่พวกเขาเปิดแล้วการเปลี่ยนแปลง "Activesheet" และสมุดงานเป้าหมายสำหรับคำสั่ง "Select" ที่ไม่มีเงื่อนไขก็จะเปลี่ยนเช่นกัน

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

ฉันมีกฎทองธรรมดาที่ฉันติดตาม: เพิ่มตัวแปรชื่อ "wb" และ "ws" สำหรับวัตถุสมุดงานและวัตถุแผ่นงานและใช้สิ่งเหล่านั้นเพื่ออ้างอิงถึงหนังสือมาโครของฉันเสมอ ถ้าฉันต้องการอ้างถึงหนังสือมากกว่าหนึ่งเล่มหรือมากกว่าหนึ่งแผ่นฉันจะเพิ่มตัวแปรเพิ่มเติม

ตัวอย่างเช่น

Dim wb as Workbook
Dim ws as Worksheet
Set wb = ThisWorkBook
Set ws = wb.sheets("Output")

คำสั่ง "Set wb = ThisWorkbook" นั้นสำคัญอย่างยิ่ง "ThisWorkbook" เป็นค่าพิเศษใน Excel และหมายถึงเวิร์กบุ๊กที่โค้ด VBA ของคุณกำลังทำงานอยู่ ทางลัดที่เป็นประโยชน์อย่างมากในการตั้งค่าตัวแปรเวิร์กบุคของคุณด้วย

หลังจากที่คุณทำสิ่งนั้นที่ด้านบนสุดของ Sub แล้วการใช้มันจะไม่ง่ายกว่านี้เพียงใช้พวกมันทุกที่ที่คุณจะใช้ "Selection":

ดังนั้นหากต้องการเปลี่ยนค่าของเซลล์ "A1" ใน "Output" เป็น "Hello" แทนที่จะเป็น:

Sheets("Output").Activate
ActiveSheet.Range("A1").Select
Selection.Value = "Hello"

ตอนนี้เราสามารถทำสิ่งนี้:

ws.Range("A1").Value = "Hello"

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

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


1
ไม่ใช่ downvote ของฉัน แต่ฉันไม่แน่ใจว่าสิ่งนี้จะเพิ่มสิ่งใหม่ ๆ ให้กับสิ่งที่ได้รับการเสนอในคำตอบที่มีอยู่แล้ว
BigBen

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

แต่คำตอบที่ได้รับการยอมรับพูดถึงอย่างแน่นอนThisWorkbook... ฉันไม่แน่ใจว่าความคิดเห็นของคุณถูกต้อง
BigBen

ใช่คุณไม่ผิด แต่ไม่ใช่ในบริบทของการใช้มันเพื่อตั้งค่าตัวแปรเวิร์กบุ๊กและการใช้ตัวแปรเวิร์กบุ๊กในอนาคตหรือการใช้ตัวแปรเวิร์กบุคนั้นเพื่อตั้งค่าตัวแปรเวิร์กชีทตามที่ฉันแนะนำ คำตอบของฉันสั้นง่ายและเข้าถึงได้ง่ายสำหรับผู้เริ่มต้นมากกว่าคำตอบที่ยอมรับ
Geoff Griswald

-3

นี่คือตัวอย่างที่จะล้างเนื้อหาของเซลล์ "A1" (หรือมากกว่านั้นหากประเภทการเลือกคือ xllastcell ฯลฯ ) ทำทั้งหมดโดยไม่ต้องเลือกเซลล์

Application.GoTo Reference:=Workbook(WorkbookName).Worksheets(WorksheetName).Range("A1")
Range(Selection,selection(selectiontype)).clearcontents 

ฉันหวังว่านี่จะช่วยให้ใครบางคน


1
ไม่ล่ะขอบคุณ. นั่นไม่ใช่สิ่งที่คุณทำเลย สิ่งที่คุณทำจริง ๆ คือการเลือกเซลล์ "A1" โดยใช้คำสั่ง "Application.GoTo" ซึ่งไม่แตกต่างจากการใช้ "เลือก" จริง ๆ แล้วใช้เนื้อหาที่ชัดเจนในการเลือกของคุณ วิธีที่จะทำโดยไม่ต้องเลือกเซลล์จะWorkbook(WorkbookName).Worksheets(WorksheetName).Range("A1").ClearContentsเป็นหนึ่งบรรทัดและไม่สองเซลล์และใช้งานได้จริงโดยไม่เลือกเซลล์
Geoff Griswald
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.