Range.Replace เป็นจริงเสมอสำหรับ Chr(1)

ตอนนี้ฉันสับสน ฉันจะสร้างคำตอบสำหรับ คำถามนี้

เมื่อทำการทดสอบบางอย่างฉันสังเกตเห็นว่า

ActiveSheet.Cells.Replace Chr(1), "", xlPart, , True, , False, False

เคลียร์แผ่นงานออกหมด มันสมเหตุสมผลสำหรับ Chr(42) ซึ่งก็คือ * แต่ทำไม Chr(1)

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


person Dirk Reichel    schedule 10.08.2017    source แหล่งที่มา
comment
น่าสนใจ. ต้องเป็นคุณลักษณะบางอย่างที่ไม่ได้จัดทำเป็นเอกสาร   -  person A.S.H    schedule 10.08.2017
comment
แค่ 1 ชั่วโมง...แต่รู้สึกว่าจะจบลงด้วยเงินรางวัลนะ... [A1].value = "-" & Chr(1) & "-" ดูแปลกๆ ดี :D   -  person Dirk Reichel    schedule 10.08.2017
comment
สิ่งนี้น่าสนใจมาก นี่คือสิ่งที่ฉันพบ Chr(1) หมายถึง Start of Heading และนี่คือเอกสาร (cs.tut.fi/~ jkorpela/chars/c0.html) อธิบายอักขระควบคุม ASCII ทั้งหมด เว็บไซต์ของรัฐบาลอื่น (its.bldrdoc.gov/fs-1037/ dir-034/_5089.htm) มีคำอธิบายที่ดีกว่าและยังน่าสับสนสำหรับ Chr(1)   -  person ian0411    schedule 25.08.2017
comment
@ ian0411 ฉันรู้ว่า chr(1) คืออะไร ฉันแค่สับสนว่าทำไม Excel ทำหน้าที่เหมือนกับที่จะทำกับเครื่องหมายดอกจัน (ตัวยึดตำแหน่ง) แต่ไม่ใช่สำหรับอักขระอื่น ๆ ที่ไม่สามารถพิมพ์ได้ ดูเหมือนว่ามีบางสิ่งที่อยู่ลึกเข้าไปในแอปพลิเคชันนั้นเองที่ทำให้ Excel สับสน ฉันใจดีถ้าอยากรู้ว่าเกิดอะไรขึ้นที่นั่น (แต่ผมมั่นใจว่าผมไม่สามารถเข้าใจได้จริงนะครับ) :P   -  person Dirk Reichel    schedule 25.08.2017
comment
ฉันก็สับสนเหมือนคุณ คุณอาจพบฟีเจอร์สัตว์ประหลาดที่ MS ไม่รู้ด้วยซ้ำ   -  person ian0411    schedule 25.08.2017
comment
สิ่งที่น่าสนใจยิ่งกว่านั้นคือ - Chr(1) - ย้ายส่วนสุดท้าย - เหนือช่องว่าง แต่ไม่สามารถเลือกได้... และคุณไม่สามารถค้นหาและแทนที่ Chr(1) โดยไม่มี VBA   -  person seadoggie01    schedule 13.09.2017
comment
ฉันคิดว่า Chr(1) เป็นตัวยึดตำแหน่งที่แท้จริง (ไม่เช่นนั้นจะไม่สามารถค้นหา *) ได้ แต่การไม่มีทางทำเช่นนั้นได้ (เท่าที่ฉันรู้) มันอาจจะเหลืออยู่บ้าง ถึงกระนั้นหากไม่มีโปรแกรมเมอร์มาหยุดที่นี่โดยบังเอิญ ฉันสงสัยว่าฉันจะได้รับคำตอบที่ถูกต้องหรือไม่ :/   -  person Dirk Reichel    schedule 13.09.2017
comment
เพื่อแจ้งให้ทราบ แม้ว่าจะไม่ใช่ปัญหาเดียวกันมากนัก แต่ก็อาจเป็นเรื่องที่น่าสนใจที่จะดูว่าทำไม Application.Clean จึงลบอักขระที่พิมพ์ได้ stackoverflow.com/questions/27641324 /   -  person T.M.    schedule 20.09.2017
comment
Chr(63) ซึ่งก็คือ ? ทำสิ่งเดียวกัน   -  person Karthick Gunasekaran    schedule 22.09.2017
comment
@KarthickGunasekaran ? เป็นตัวยึดตำแหน่งสำหรับอักขระตัวเดียวในขณะที่ * เป็นตัวยึดตำแหน่งสำหรับอักขระจำนวนเท่าใดก็ได้...   -  person Dirk Reichel    schedule 22.09.2017
comment
@Dirk Reichel แล้วทำไมมันถึงทำความสะอาดตัวละครทั้งหมดในแผ่นงาน   -  person Karthick Gunasekaran    schedule 22.09.2017
comment
@KarthickGunasekaran เพราะคุณกำลังมองหา xlPart ดังนั้นเหตุการณ์ทั้งหมดจะถูกแทนที่ (หากแทนที่ a ด้วย c ดังนั้น aba จะกลายเป็น cbc) วิธีนี้จะทำให้สตริงทั้งหมดถูกล้าง char โดย char) ;)   -  person Dirk Reichel    schedule 23.09.2017
comment
ข้อมูลเพิ่มเติมเกี่ยวกับ chr(1) ที่นี่ และ ที่นี่.   -  person ashleedawg    schedule 18.10.2017
comment
@DirkReichel ดูค่อนข้างแปลก ดังนั้นควรทำตัวอักษรไม่เกิน 7 เมื่อเพิ่งเข้าไปในเซลล์   -  person Luuklag    schedule 24.10.2017
comment
เป็นกรณีที่น่าสนใจจริงๆ ฉันพบว่าเมื่อเพิ่ม Chr(1) หลายอินสแตนซ์ลงในเซลล์เดียวแล้วแทนที่ด้วยค่าสุ่ม มันจะแทนที่เพียงครั้งเดียวในเซลล์นั้น ดังนั้นฉันคิดว่ามันไม่ได้มองหาค่านั้นจริงๆ แต่แทนที่เซลล์ใดๆ ที่ไม่ว่างเปล่า   -  person Slaqr    schedule 22.11.2017
comment
เมื่อแทรกหลายอินสแตนซ์ของ Chr(1) ลงในสตริงแล้วเรียกใช้การแทนที่ มันจะจับอินสแตนซ์ทั้งหมด ดูเหมือนว่าพฤติกรรมแปลก ๆ นี้จะเกิดขึ้นเมื่อมีการอ้างอิงเซลล์โดยตรงเท่านั้น   -  person Slaqr    schedule 22.11.2017
comment
มันส่ง ข้อผิดพลาดรันไทม์ '9': ตัวห้อยอยู่นอกช่วง มาให้ฉัน :/   -  person AntiDrondert    schedule 28.11.2017
comment
ด้วยความอยากรู้อยากเห็น - เมื่อคุณทำเช่นนี้ หากคุณบันทึกเวิร์กบุ๊กในภายหลัง มันจะเสียหายในทางใดทางหนึ่งเมื่อคุณลองเปิดมันอีกครั้งหรือไม่   -  person SierraOscar    schedule 13.12.2017
comment
ฉันเดาว่าพฤติกรรมของ Excel เชื่อมโยงกับการตีความ chr(1) ลองเรียกใช้: SendKeys Chr(1) ทำงานเหมือน CTRL+A, Chr(2) ทำงานเหมือน CTRL+B ฯลฯ (รายละเอียดเพิ่มเติมที่นี่ dc .org/files/asciitable.pdf) อาจเป็นไปได้ว่า vba แปล chr(1) เป็น 'เลือกทั้งหมด' ดังนั้นเซลล์ที่ไม่ว่างทั้งหมดจึงถูกแทนที่   -  person TomJohnRiddle    schedule 22.01.2018
comment
@TomJohnRiddle ที่จริงแล้ว Chr(1) (รวมถึงสิ่งอื่น ๆ ) ไม่รองรับ windows คุณเดาว่ามันถูกต้อง การตีความ Chr(1) ของ Excel จะเป็นการเลือกทุกอย่าง ในกรณีของ OP มันจะแทนที่ด้วยเซลล์ว่าง แต่ดูว่าจะเกิดอะไรขึ้นเมื่อคุณพยายามแทนที่ด้วย Hello สิ่งนี้จะใช้ได้กับช่วงอื่นด้วย :)   -  person JvdV    schedule 03.08.2018
comment
ฉันไม่แน่ใจเกี่ยวกับการเลือกทุกส่วน มันสมเหตุสมผลในทางใดทางหนึ่ง แต่การแทนที่เป็นฟังก์ชันที่จะเปรียบเทียบ 2 สาย หากมี 2.0 และคุณพยายามแทนที่ 0 ด้วยบางอย่าง จะไม่มีอะไรเกิดขึ้น แต่เมื่อถึง 2.01 มันจะเป็นเช่นนั้น ดังนั้นค่าตัวเลขจะถูกแปลง (ละเว้นการจัดรูปแบบตัวเลข) เพียงแค่ค้นหาตัวเลขหรือสตริงก็ไม่สำคัญ มันเพียงเปรียบเทียบ 2 สาย จะไม่มีการเลือกเซลล์หรือข้อความภายในเซลล์ หากฟังก์ชันนี้เลือกบางอย่าง มันจะช้ามาก การมี ch(1) อยู่ในเซลล์ก็ไม่สามารถพลิกเอฟเฟกต์ได้   -  person Dirk Reichel    schedule 15.08.2018
comment
แม้ว่า ActiveSheet.Cells.Find(Chr(1), ActiveCell).Activate จะทำงานเหมือนกับเป็นไปตามเงื่อนไขเสมอ แต่วิธีการเปรียบเทียบอื่นๆ จะไม่แสดงพฤติกรรมดังกล่าว เช่น instr() และเช่นเดียวกับคำใบ้: สิ่งนี้จะใช้ได้หากคุณเปิดหน้าต่างแทนที่และวางนิพจน์ Chr(1) ลงในช่องค้นหา และในทางกลับกันสำหรับการเลือกทั้งหมด: Microsoft Word จะไม่แสดงพฤติกรรมนี้เลย   -  person Dirk Reichel    schedule 15.08.2018


คำตอบ (4)


สาเหตุสามารถอนุมานได้จากความแตกต่างระหว่าง

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

  • SOH : อักขระนี้ใช้เพื่อระบุจุดเริ่มต้นของส่วนหัว ซึ่งอาจมีที่อยู่หรือข้อมูลเส้นทาง

  • STX : อักขระนี้ใช้เพื่อระบุจุดเริ่มต้นของข้อความ และในลักษณะนี้ยังใช้เพื่อระบุจุดสิ้นสุดของส่วนหัวด้วย

แหล่งที่มาของคำจำกัดความ


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

ใน Hadoop นั้น SOH มักใช้เป็นตัวคั่นฟิลด์โดยเฉพาะในขณะที่อ่านไฟล์ CSV นอกจากนี้ เมื่อเปิดไฟล์ Excel (โดยไม่ต้องแตกไฟล์เป็น xlsx ธรรมดา เช่น ไบนารี่) ใน Notepad++ และพิมพ์อักขระควบคุม เราจะเห็นอักขระ SOH จำนวนมาก เนื่องจากคุณสมบัติด้านความปลอดภัย จึงไม่สามารถมองเห็นข้อมูลจริงได้

chr(0) = SOH เป็นตัวชี้ไปยังที่อยู่หน่วยความจำของเซลล์ทั้งหมดที่มี TEXT

และ

chr(1) = NUL เป็นตัวชี้ไปยังที่อยู่หน่วยความจำของเซลล์ทั้งหมดที่มี NULL หรือ BLANK CELLS

ลองดูข้อความข้างต้นตามคำสั่งต่างๆ ที่แสดงในภาพด้านล่าง ซ้ายบนคือช่วงข้อมูลดั้งเดิม และตัวอย่างแสดงให้เห็นว่าการแทนที่ทำงานอย่างไรสำหรับ SOH, NUL และ ASTERISK (*) โดยใช้ฟังก์ชัน Range.Replace

SOH แทนที่ทั้งหมดใน EXCEL


ดังนั้นเหตุใด Chr(0) และ Chr(1) จึงสามารถแทนที่ค่าในเซลล์ Excel ได้หากเป็นเพียงตัวชี้ที่อยู่และ chr(1) ทำหน้าที่แตกต่างจาก chr(42) อย่างไร

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

อย่างไรก็ตาม ทันทีที่มีเซลล์ใดเข้าสู่เซลล์ B2 เซลล์ว่างทั้งหมดที่ยกกำลังสองไปจนถึง B2 จะถูกกำหนดตัวชี้ด้วย Chr(0) และเซลล์ B2 จะถูกกำหนดตัวชี้ด้วย Chr(1)

ตอนนี้ ถ้าใครลบเนื้อหาของเซลล์ B2 เซลล์ B2 จะถูกกำหนดตัวชี้ NUL หรือ Chr(0) ให้กับเซลล์นั้นพร้อมกับเซลล์อื่นๆ

นี่เป็นเหตุผลว่าทำไมการล้างเนื้อหาโดยใช้ Cells.ClearContents เท่านั้นจะไม่ล้างเซลล์ในหน่วยความจำ และเวิร์กบุ๊ก Excel จะขยายใหญ่ขึ้นเมื่อมีการใช้เซลล์ที่อยู่ห่างไกลแต่ไม่ถูกลบโดยใช้ Cells.Clear หรือ Ctrl+Delete


ขณะนี้เป็นที่ชัดเจนว่าเหตุใด Excel จึงแทนที่เนื้อหาหรือล้างแผ่นงานด้วยคำสั่งที่กำหนด สิ่งสำคัญคือต้องเข้าใจความแตกต่างระหว่างเครื่องหมายดอกจัน (*) และ SOH [หรือ Chr(0)]

เครื่องหมายดอกจัน (*) แทนที่เนื้อหาของเซลล์ที่มีความยาวขั้นต่ำ 0

ในขณะที่ Chr(0) ระบุเซลล์ด้วย SOH เช่นเซลล์ที่มีค่าแล้วแทนที่ค่าที่ปลายทางของตัวชี้

ความแตกต่างไม่ได้อยู่ที่ผลลัพธ์ แต่อยู่ที่วิธีการค้นหาหรือระบุเซลล์ที่จะแทนที่


ฉันสร้างมาโครขนาดเล็กเพื่อตรวจสอบสมมติฐานที่ฉันบันทึกเวลาที่ใช้ในการแทนที่ครึ่งล้านเซลล์ (A1 ถึง CZ5000) โดยใช้ Chr(1) = SOH และ Chr(42) = *

ปรากฎว่าการใช้ตัวชี้ไปยังที่อยู่ของเซลล์ที่มีข้อความ เช่น SOH ใช้เวลาน้อยกว่าเครื่องหมายดอกจัน (*)

เวลาที่ใช้ในการแทนที่ข้อความ


Sub Replace_Timer()

    Sheet3.Activate

    Dim startTime, endTime
    Dim i As Integer

        Sheet3.Range("A1:CZ5000").Value = "A"

    For i = 1 To 25
        startTime = Timer
            Sheet3.Cells.Replace Chr(1), "X", xlPart, xlRows, False
        endTime = Timer
        Sheet4.Cells(i + 1, 2).Value = endTime - startTime 'Execution time in miliseconds

        startTime = Timer
            Sheet3.Cells.Replace Chr(42), "Z", xlPart, xlRows, False
        endTime = Timer

        Sheet4.Cells(i + 1, 3).Value = endTime - startTime 'Execution time in miliseconds
    Next

    Sheet4.Activate

End Sub
person jainashish    schedule 21.02.2019
comment
คำตอบนี้อธิบายทุกอย่างโดยละเอียดในขณะที่เข้าใจง่าย เพื่อแสดงความขอบคุณต่อคำตอบที่ยอดเยี่ยมนี้ ฉันได้เพิ่มเงินรางวัล 100 แต้ม ซึ่งจะนำไปใช้โดยเร็วที่สุด (รางวัลจะถูกล็อคเป็นเวลา 24 ชั่วโมง) - person Dirk Reichel; 23.02.2019
comment
ฉันไม่แน่ใจว่าเกณฑ์มาตรฐานของคุณถูกต้อง - เมื่อฉันเรียกใช้โค้ดนี้ ฉันจะได้รับการกระจายผลลัพธ์ที่เกือบจะสมบูรณ์แบบสำหรับการวนซ้ำ 25 ครั้ง โดยประมาณครึ่งหนึ่งของการรันใช้เวลานานกว่าในแต่ละวิธี ฟังก์ชัน Timer ยังส่งคืนวินาที ไม่ใช่มิลลิวินาที ;-) - person Comintern; 23.02.2019
comment
น่าสนใจมาก. - person S Meaden; 25.02.2019

ASCII 1 คือ 'SOH' (จุดเริ่มต้นของส่วนหัว) และ ASCII 2 'STX' หมายถึงจุดสิ้นสุดของส่วนหัวซึ่งเป็นจุดเริ่มต้นของสตรีมข้อมูล (ซึ่งช่วยให้คุณสามารถ 'ซ่อน' ที่อยู่ บันทึกย่อ หรืออะไรก็ได้ในไฟล์ที่อยู่ข้างหน้าข้อมูลจริงในไฟล์) ดูเหมือนว่า Excel กำลังตีความคำสั่งของคุณให้เริ่มต้นที่จุดเริ่มต้นของไฟล์และรวมทุกอย่างไว้

person tysonwright    schedule 02.03.2018
comment
AFAIK excel ตรวจสอบสตริงภายในเซลล์โดยตรง (ไม่ใช่ข้อมูลโดยรวม) แม้ว่าสิ่งนี้จะรวมถึงการจัดรูปแบบ แต่จะไม่สนใจโครงสร้าง (ดังนั้นคุณจึงไม่ทำให้ไฟล์เสียหาย) - person Dirk Reichel; 16.03.2018

ฉันคิดว่าฉันพบคำตอบแล้ว
ฉันพบได้อย่างไร
ฉันพิมพ์ "Alt+1" (1 จากแป้นตัวเลข) แล้วฉันได้สิ่งนี้ "?" (เครื่องหมายคำถาม)
ตอนนี้ฉันพิมพ์โค้ดด้านล่าง ซึ่งจะเป็นการล้างชีต

ActiveSheet.Cells.Replace "?", "", xlPart, , True, , False, False
person Community    schedule 15.03.2018
comment
Chr(1) ส่งคืน SOH ที่สามารถพิสูจน์ได้ นั่นไม่ใช่เหตุผลขอโทษ :( - person Dirk Reichel; 16.03.2018
comment
ฉันลองใน Excel แล้ว Alt+1 ทำให้ฉันมีหน้ายิ้ม แต่ในหน้าต่างทันทีของ VBA มันให้เครื่องหมายคำถาม ! อย่างไรก็ตาม Alt + 2, Alt+3, Alt+4 และอื่นๆ --> ทั้งหมดแสดงเครื่องหมายคำถามในหน้าต่าง Immediate VBA และไม่ได้ล้างแผ่นงาน คุณพยายามอย่างดีแล้ว แต่น่าเสียดาย นั่นไม่ใช่วิธีแก้ปัญหาที่ถูกต้อง - person jainashish; 03.07.2018

ASCII 1 ตามที่หลายๆ คนระบุ แอปพลิเคชันจะตีความว่าเป็นจุดเริ่มต้นของส่วนหัวของอักขระแต่ละตัว อย่างไรก็ตาม อักขระพิเศษสามารถหลีกได้ด้วยอักขระอื่น ('~' คืออักขระหลีกใน Excel) ตรวจสอบที่นี่

ฉันเชื่อว่าคุณควรหลีกเลี่ยงการแทนที่ด้วย ch(1) ในโค้ดของคุณ

person Sonu Kumar    schedule 22.03.2018