รับค่าเซลล์ใน Excel จากช่วง

ฉันจะแยกค่าของเซลล์ออกจากวัตถุช่วงได้อย่างไร ดูเหมือนว่ามันควรจะง่าย คำถาม Stackoverflow นี้และ คำตอบไม่ได้ช่วยอะไรจริงๆ นี่คือสิ่งที่ฉันต้องการทำ แต่ล้มเหลวทุกครั้งโดยมีข้อยกเว้นใน row.columns(0,0)

Dim rdr = oFindings.Range
For Each row As Excel.Range In rdr.Rows
   Dim Account = row.Columns(0,0).value2.tostring
   ' Do other stuff
Next

เพื่อให้ได้ผล ฉันต้องใช้โค้ดนี้:

For Each row As Excel.Range In rdr.Rows
    ndx = 0
    For Each cell As Excel.Range In row.Columns
        If ndx = 0 Then Account = NS(cell.Value2)
        ' Do other stuff
        ndx += 1
    next
Next

นั่นดูเหมือนเป็นเรื่องไร้สาระ ความลับคืออะไร?


person Ebassador    schedule 02.09.2015    source แหล่งที่มา
comment
พวกเขาทั้งหมดมีประเภทเดียวกันหรือไม่? คุณรู้ชนิดของเซลล์ล่วงหน้าหรือไม่?   -  person SpaceSteak    schedule 02.09.2015
comment
ข้อยกเว้นใน row.columns(0,0) ดูเหมือนว่าสมเหตุสมผลจนถึง Excel (และคอลเลกชัน 2D ใด ๆ ใน VB.NET หรือในภาษาอื่น ๆ ที่ฉันรู้) คาดหวังเพียง 2 ดัชนีและคุณกำลังให้ 3 แถวตัวแปรภายใน foreach วนซ้ำ เหมือนกับ rdr.Rows(indexRow); จากนั้นคุณกำลังเพิ่มดัชนีอีกสองดัชนีลงในคอลัมน์ ไวยากรณ์ที่ถูกต้องคือ row.Columns(0)   -  person varocarbas    schedule 02.09.2015
comment
0 ไม่ใช่ rowindex หรือ columnindex ที่ถูกต้องใน Excel VBA   -  person Ron Rosenfeld    schedule 02.09.2015
comment
@RonRosenfeld ประการแรกนี่ไม่ใช่ VBA และประการที่สอง 0 เป็นดัชนี VBA ที่ถูกต้องในฟังก์ชันบางอย่าง (ไม่ใช่ในเซลล์ Excel) ปัญหาที่นี่คือกำลังป้อน 3 ดัชนีแทนที่จะเป็นเพียง 2 (ปัญหาใน VBA และที่นี่ใน VB.NET)   -  person varocarbas    schedule 02.09.2015
comment
@varocarbas ขอบคุณสำหรับการชี้แจง ฉันได้รวมไว้ในความคิดเห็นของฉันว่านำไปใช้กับ Excel VBA และในภาษานั้น Columns(0,0) ไม่ใช่การอ้างอิงช่วงที่ถูกต้อง ฉันไม่แน่ใจว่าจะนำไปใช้กับปัญหาของ OP ได้อย่างไร แต่ฉันรู้สึกว่าอาจเป็นข้อมูลที่เป็นประโยชน์   -  person Ron Rosenfeld    schedule 02.09.2015
comment
@RonRosenfeld (บางทีฉันอาจเข้าใจผิด a นิรนัย ประโยคที่ชัดเจนมาก 0 ไม่ใช่ rowindex หรือ columnindex ที่ถูกต้องใน Excel VBA ขออภัยเกี่ยวกับเรื่องนั้น แต่การชี้แจงไม่เคยมีปัญหาใช่ไหม) ไม่ว่าในกรณีใด โปรดจำไว้ว่าใน VBA Columns(0,0) นั้นผิดพอ ๆ กับ Columns(2,2) เท่าที่ Columns() คอลเลกชันอนุญาตเพียงหนึ่งดัชนีเท่านั้น (เทียบเท่ากับคอลเลกชันส่วนใหญ่ที่เรียกว่าคอลัมน์ซึ่งโดยปกติจะเป็นส่วนหนึ่ง ของการจำลองตาราง เช่น DataTable ใน .NET) การชี้แจงนี้ตกลงหรือฉันตั้งใจของคุณผิดอีกครั้งหรือไม่   -  person varocarbas    schedule 02.09.2015
comment
โปรดทราบว่าขอแนะนำอย่างยิ่ง ไม่ ใช้ row หรือ cell เป็นตัวแปร เนื่องจาก Row และ Cell หมายถึงบางสิ่งโดยนัยสำหรับ VBA ฉันจะเปลี่ยนตัวแปรนั้นเป็น xRow หรือ cel หรืออะไรสักอย่าง ไม่อยากให้เกิดความสับสนใดๆ ทั้งสิ้น!   -  person BruceWayne    schedule 02.09.2015
comment
@RonRosenfeld ฉันจะให้เครดิตใครกับอันนี้? มันเป็นปัญหาของการใช้สองดัชนีภายใน For loop และ Excel เป็นแบบอิง 1 ไม่ใช่แบบศูนย์ Stackoverflow พิสูจน์ให้เห็นอีกครั้งว่าเป็นทรัพยากรที่ยอดเยี่ยม! ขอบคุณมาก!   -  person Ebassador    schedule 02.09.2015
comment
@varocarbas ฉันขอโทษ ความช่วยเหลือของคุณได้รับการชื่นชมอย่างมาก   -  person Ebassador    schedule 02.09.2015
comment
@varocarbas ฉันไม่สามารถโต้แย้งกับสิ่งที่คุณค้นพบได้ นั่นคือเหตุผลที่ฉันถามคำถามตั้งแต่แรก อย่างที่คุณพูด .Net เป็นแบบ 0 อย่างไรก็ตาม ในกรณีนี้ ไม่ว่าฉันจะใช้ (0,0) หรือเพียงแค่ (0) ฉันก็ยังคงได้รับข้อยกเว้น นอกจากนี้ การแก้ไขโค้ด (VB.NET ไม่ใช่ VBA) จำเป็นต้องใช้ (1) ฉันขอโทษที่ฉันไม่ได้มีความรู้ทั้งหมดที่คุณทำอย่างเห็นได้ชัด ฉันแค่พยายามเรียนรู้สิ่งใหม่ในแต่ละวัน Stackoverflow ช่วยฉันด้วย! ฉันรักมัน.   -  person Ebassador    schedule 02.09.2015
comment
@varocarbas เพื่อชี้แจงเพิ่มเติมถึงจุดที่ฉันพยายามทำ: rowindex และ columnindex เป็นอาร์กิวเมนต์ที่มีชื่อสำหรับวัตถุช่วง VBA ต่างๆ ประเด็นของฉันคือ นอกเหนือจากสิ่งที่คุณได้ชี้ให้เห็นแล้วเกี่ยวกับความไม่ถูกต้องของวัตถุคอลัมน์ของ OP ที่มีสองอาร์กิวเมนต์ใน VBA อาร์กิวเมนต์นั้นต้องไม่เป็นศูนย์   -  person Ron Rosenfeld    schedule 02.09.2015
comment
แนวคิดสองสามข้อสำหรับผู้อ่านในอนาคต IDEA 1: นี่คือ VB.NET (ใช้ร่วมกับ Excel ผ่าน Interop แต่อาศัยกฎ .NET อย่างเต็มที่ เช่น อาร์เรย์ทั้งหมดเป็นแบบ 0-BASED) IDEA 2: ปัญหาของโค้ดนี้คือ row.Columns(0,0) ซึ่งตามที่อธิบายไว้ข้างต้นผิด (รวมถึงอธิบายการแก้ไขด้วย) มันก็จะผิดใน VBA เช่นกันเนื่องจากใช้สองดัชนี (ศูนย์หรือตัวเลขอื่นใด) IDEA 3: VBA (ไม่ใช่ VB.NET) เป็นแบบ 1 เฉพาะในบางส่วนเท่านั้น (เช่นเซลล์) แต่ไม่ใช่ในส่วนอื่น ๆ (อาร์เรย์) และอาจถูกแปลงเป็นแบบศูนย์ (นี่เป็นเพียงพฤติกรรมเริ่มต้น)   -  person varocarbas    schedule 02.09.2015
comment
เอกอัครราชทูต คุณต้องเข้าใจว่าการที่มันล่มในสถานการณ์เฉพาะของคุณไม่ได้ทำให้มันผิดอย่างแน่นอน (โค้ดของคุณอาจไม่สมบูรณ์แบบใช่ไหม) หากคุณไม่มีความรู้มากเกินไปเกี่ยวกับบางสิ่งบางอย่าง และบางคน (ดูเหมือน) ที่มีความรู้มากกว่าในเรื่องนี้กำลังพูดอะไรบางอย่างกับคุณ บางทีคุณไม่ควรคิดว่าการตีความแบบสุ่มอาจเป็นการดีที่จะโต้เถียงกับบุคคลเช่นนั้น ฉันยืนยันว่า: .NET (คอลเลกชันทั้งหมดในภาษา .NET) เป็นแบบศูนย์ เมื่อคุณอ่านจาก Excel ข้อมูลจะถูกจัดเก็บไว้ในคอลเลกชัน .NET (ไม่เกี่ยวข้องกับ VBA) ซึ่งเป็นแบบ 0   -  person varocarbas    schedule 02.09.2015
comment
PS: สาเหตุที่เป็นไปได้มากที่สุดสำหรับปัญหาของคุณคือคุณกำลังทำ .value2.ToString() โดยไม่ได้ตรวจสอบว่า .value2 เป็นโมฆะจริง ๆ หรือไม่ (เป็นความคิดที่แย่มากเพราะถ้าเป็นโมฆะ ToString() จะไม่มีอยู่และข้อผิดพลาดจะเกิดขึ้น ถูกกระตุ้น) เซลล์แรกในสเปรดชีตของคุณ (rdr.Rows(0).Columns(0) ใน VB.NET) มีแนวโน้มว่าจะว่างเปล่า ค่า 2 เป็นโมฆะ และคุณมีข้อผิดพลาด   -  person varocarbas    schedule 02.09.2015
comment
@ RonRosenfeld ฉันคิดว่าฉันได้ให้แนวคิดเหล่านี้ชัดเจนในความคิดเห็นต่าง ๆ แต่ในกรณีที่มีการชี้แจงใหม่: คอลเลกชันคอลัมน์ใน VBA (ไม่มีความสัมพันธ์เลยกับที่กล่าวถึงในคำถามนี้ คอลเลกชันที่แตกต่างอย่างสิ้นเชิงที่มี ชื่อเดียวกันและเป็นไปตามกฎ VB.NET ดังนั้นจึงเป็นแบบอิง 0) เป็นแบบอิง 1 (สิ่งเดียวกันสำหรับแถว เซลล์ ฯลฯ) มีบางสิ่งใน VBA ค่อนข้างมาก (เช่น อาร์เรย์) ที่เป็น 0 (อย่างน้อยก็โดยค่าเริ่มต้น อาจมีการเปลี่ยนแปลงได้) ไม่ว่าในกรณีใด การยืนยันว่า VB.NET Interop ไม่มีส่วนเกี่ยวข้องกับ VBA (เป็นเพียงไวยากรณ์ที่คล้ายกัน)   -  person varocarbas    schedule 02.09.2015
comment
@varocarbas ฉันเห็นด้วย แต่ฉันเขียนเกี่ยวกับอาร์กิวเมนต์ที่มีชื่อเฉพาะซึ่งฉันพูดถึงเท่านั้น และไม่เกี่ยวกับอาร์เรย์ VBA   -  person Ron Rosenfeld    schedule 02.09.2015
comment
@RonRosenfeld ดังที่กล่าวไว้คอลเลกชันทั้งหมดที่เกี่ยวข้องกับเซลล์จริง (เช่นคอลัมน์, แถว, ชีต, สมุดงาน ฯลฯ ) และฟังก์ชั่นบางส่วนนั้นเป็นแบบ 1 จริงๆ แต่ไม่ใช่ทุกอย่างใน VBA จะเป็นแบบ 1 ตามค่าเริ่มต้น   -  person varocarbas    schedule 02.09.2015


คำตอบ (1)


ปัญหาส่วนใหญ่ได้รับการกล่าวถึงแล้ว แต่นี่คือคำตอบพร้อมโค้ด

    Dim rdr As Excel.Range = oFindings.Range
    For Each row As Excel.Range In rdr.Rows

        'explicitly get the first cell as a range 
        Dim aCell As Excel.Range = row.Cells(1, 1)

        'explicity convert the value to String but don't use .String
        Dim Account as string = CStr(aCell.Value2)

        If Not String.IsNullOrEmpty(Account) Then

            ' Do other stuff

        End If

    Next

การใช้ aCell.Value2.toString จะล้มเหลวหากเซลล์ว่าง เนื่องจาก Value2 จะเป็น Nothing ใช้ CStr(aCell.Value2) ซึ่งจะไม่ล้มเหลวแทน แต่คุณต้องทดสอบว่าสตริงเป็นโมฆะหรือว่างเปล่าก่อนที่จะใช้ค่า

person D_Bester    schedule 03.09.2015