ย้ายคอลัมน์ที่ซ้ำกันไปยังคอลัมน์ที่ไม่ซ้ำ

ฉันสงสัยว่าเป็นไปได้หรือไม่ที่จะย้ายคอลัมน์ที่มีเขตข้อมูลซ้ำที่จัดกลุ่มไว้ เช่น:

+---------+------+
| field_1 | 1    |
| field_2 | 2    |
| field_3 | 3    |
| field_4 | 4    |
| field_1 | 5    |
| field_2 | 6    |
| field_3 | 7    |
| field_4 | 8    |
| field_1 | 9    |
| field_2 | 10   |
| field_3 | 11   |
| field_4 | 12   |
+---------+------+

ไปยังคอลัมน์ที่ไม่ซ้ำ เช่นนี้

+---------+---------+---------+---------+
| field_1 | field_2 | field_3 | field_4 |
+---------+---------+---------+---------+
| 1       | 2       | 3       | 4       |
| 5       | 6       | 7       | 8       |
| 9       | 10      | 11      | 12      |
+---------+---------+---------+---------+

เป็นไปได้ไหมหากไม่มีสคริปต์?


person vedar    schedule 25.05.2016    source แหล่งที่มา
comment
หากไม่มีสคริปต์ (เช่น การใช้ vba) คำถามของคุณอาจถูกถามที่ไซต์ในเครือ superuser.com   -  person surfmuggle    schedule 26.05.2016
comment
@slackmuggle ค่อนข้างบ่อยในการทำสิ่งต่าง ๆ ใน Excel โดยไม่ต้องใช้สคริปต์ มีแท็กทั้งหมดสำหรับ excel-formula นั้น ซึ่งควรจะเพิ่ม   -  person Forward Ed    schedule 26.05.2016
comment
@ForwardEd นี่อาจจะเป็นไปได้มาก แต่ความเข้าใจของฉันก็คือว่านี่จะเหมาะสมกว่าที่ superuser.com   -  person surfmuggle    schedule 26.05.2016


คำตอบ (3)


ป้อนสูตรด้านล่างใน E3 (โดยใช้ Ctrl+Shift+Enter) จากนั้นกรอกลงไปแล้วข้าม

=OFFSET($C$1,LARGE((ROW($B$2:$B$13)-1)*($B$2:$B$13=E$2),ROW()-2),0) & ""

ป้อนคำอธิบายรูปภาพที่นี่

ค่าไม่อยู่ในลำดับที่แสดง แต่อย่างน้อยก็อยู่ในคอลัมน์ที่ถูกต้อง

จะพยายามอธิบายว่า:

  • ค่าทั้งหมดที่เราต้องการสำหรับค่า "ฟิลด์" ที่แตกต่างกันแต่ละค่าจะถูกชดเชยด้วยจำนวน "x" ของแถวจาก C1
  • การใช้ "field_1" เป็นตัวอย่าง (ROW($B$2:$B$13)-1)*($B$2:$B$13=E$2) จะส่งกลับอาร์เรย์ของหมายเลขแถวคูณด้วย 1 (TRUE) หรือศูนย์ (FALSE) ขึ้นอยู่กับว่าค่าในเซลล์ "B" ตรงกับ "field_1" (จาก E2) หรือไม่ -1 เป็นการปรับเนื่องจากเราเริ่มต้นจากแถวที่ 2 อาร์เรย์ที่ส่งคืนจะมีลักษณะดังนี้:

    [1,0,0,0,5,0,0,0,9,0,0,0]

  • เมื่อพิจารณาจากอาร์เรย์นั้น เราจำเป็นต้องหาวิธีเพื่อให้ได้ค่าที่ไม่ใช่ศูนย์ทีละค่า: เราสามารถใช้ LARGE() เพื่อทำเช่นนั้น โดยเพิ่มอาร์กิวเมนต์ที่สองเป็น LARGE โดยใช้ ROW()-2 (-2 เพราะเราต้องการให้อาร์กิวเมนต์ที่สองนั้น เริ่มต้นที่ 1 และกำลังป้อนสูตรในแถวที่ 3) สิ่งนี้ทำให้เรามีอาร์เรย์ของค่าที่เรียงลำดับ:

    [9,5,1,0,0,0,0,0,0,0,0,0]

  • เราส่งอาร์เรย์ที่เรียงลำดับนี้เป็นอาร์กิวเมนต์ "row offset" ไปที่ OFFSET() นับถอยหลังจาก C2: ค่าที่ไม่ใช่ศูนย์ทั้งหมดจะให้ค่าที่เราต้องการจาก Col C ในขณะที่ค่าศูนย์ทั้งหมดจะส่งกลับ C2 (ซึ่งว่างเปล่า และจะแสดงเป็น 0 โดยไม่มี & "" สุดท้าย

  • การอ้างอิงเซลล์ทั้งหมดในสูตรจะใช้ $ เมื่อจำเป็น ดังนั้นจึงปรับตามความจำเป็นในการลากเพื่อเติมลง/ข้าม

person Tim Williams    schedule 26.05.2016
comment
ให้ตายเถอะที่ตอบในขณะที่ฉันกำลังจัดข้าวของ! ตัวเลือกที่ดี! ฉันทำแบบเดียวกับที่คุณทำในแง่ของลำดับการแสดงผลในครั้งแรก ฉันคิดว่าถ้าคุณใช้ SMALL แทนที่จะเป็น LARGE คุณจะรักษาลำดับแนวตั้งที่ข้อมูลปรากฏ ด้วยขนาดใหญ่คุณแค่ทำงานจากล่างขึ้นบน - person Forward Ed; 26.05.2016
comment
DOH ฉันลืมไปว่าคุณจะมี 0 เท็จทั้งหมดที่มีขนาดเล็ก เมื่อวานเจอปัญหานั้น! คุณสามารถเพิ่ม COUNT($B$2:$B$13<>E$2) ใน ROW()-2 ของคุณเพื่อข้าม 0 ทั้งหมดหากคุณใช้สูตรเวอร์ชัน SMALL ได้หรือไม่ - person Forward Ed; 26.05.2016
comment
@ForwardEd - ฉันได้ดูการแทนที่ศูนย์ แต่นั่นเพิ่งเพิ่มความซับซ้อนมากขึ้นซึ่งฉันคิดว่ามันสามารถทำได้โดยไม่ต้อง ... - person Tim Williams; 26.05.2016
comment
ฉันรู้ว่าฉันต้องการ row แต่ไม่สามารถใช้งานได้ :/ คุณช่วยโพสต์สูตรเป็นข้อความแทนรูปภาพได้ไหม เพื่อที่ฉันจะได้คัดลอก/วางได้ - person findwindow; 26.05.2016
comment
อ๊ากกก ไม่ต้อง ‹333 หรอก (ล้อเล่นนะ XD) - person findwindow; 26.05.2016
comment
5555555555555555555555555555555555 ตอนนี้ฉันศึกษาไปได้ครึ่งทางแล้ว ^^ แก้ไข: คุณไม่อธิบายว่าทำไมข้อมูลจึงต้องเริ่มต้นที่ B2 แต่ฉันคิดออกแล้ว =P แก้ไข2: ฉันรู้ว่า SO ต้องการคำตอบที่อธิบาย แต่ฉันไม่ต้องการ ศึกษาเองดีกว่าครับ ^_^; - person findwindow; 26.05.2016
comment
ข้อมูลเริ่มต้นที่ B2 เพราะนั่นคือที่ที่ข้อมูลอยู่ ? - person Tim Williams; 26.05.2016
comment
โอ้ คุณกำลังรวมเส้นขอบ XD จริงๆ แล้วฉันรู้ว่าคุณสามารถลบ/เปลี่ยนคณิตศาสตร์ตามตำแหน่งได้ ^_^; - person findwindow; 26.05.2016

แค่นี้ก็พาคุณไปได้ไกลแล้ว คุณยังคงต้องลบรายการที่ซ้ำกันออก ใน D2:

=INDEX($B1:$B$12,MATCH(D$1,$A1:$A$12,0))

ป้อนคำอธิบายรูปภาพที่นี่

person findwindow    schedule 25.05.2016
comment
ไม่สามารถรับ @scottcraner ความฉลาดให้ทำงาน XD แก้ไข: ฉันคิดว่าฉันต้องการ sumproduct เอาล่ะ ได้เวลากลับบ้านแล้ว - person findwindow; 26.05.2016
comment
ฉันลงท้ายด้วยการใช้ offset จาก B1 ถึง B4: =OFFSET($B1;(ROW()-1)*3;0) จากนั้นป้อนข้อความอัตโนมัติ - person vedar; 26.05.2016
comment
@findwindow และนี่ฉันกำลังจะ +1 ให้คุณสำหรับสูตรที่กะทัดรัดและมีประสิทธิภาพขนาดนี้! - person Forward Ed; 26.05.2016
comment
@findwindow เนื่องจากคุณบอกว่าคุณมีช่วงเวลาที่ยากลำบากในการคาดเดา SUMPRODUCT เมื่อวันก่อน ฉันคิดว่าคุณอาจต้องการอ่าน ครึ่งหลังของคำตอบที่โพสต์ที่นี่ - person Forward Ed; 26.05.2016
comment
เพื่อน เราพูดอะไรเกี่ยวกับภาพหน้าจอ/คำไม่เพียงพอ XD - person findwindow; 26.05.2016

คำตอบของฉันคล้ายกับของ Tim มาก แต่หลีกเลี่ยงส่วน CSE และนำไปไว้ในฟังก์ชัน AGGREGATE เชื่อด้วยว่าจะรักษาลำดับแนวตั้งที่องค์ประกอบใน B เกิดขึ้น (ยังไม่ได้ทดสอบ)

ใน D1 ให้ใช้สูตรต่อไปนี้และคัดลอกไปทางขวาเพื่อรับรายการส่วนหัวเฉพาะของคุณ

=INDEX($A$1:$A$12,MATCH(0,INDEX(COUNTIF($C1:C1,$A$1:$A$12),0,0),0))

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

=IFERROR(INDEX($B$1:$B$12,AGGREGATE(15,6,ROW($A$1:$A$12)/($A$1:$A$12=D$1),ROW(1:1))),"Not found")

หลักฐานของแนวคิด

หลักฐานของแนวคิด

หมายเหตุเกี่ยวกับออฟเซ็ต

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

person Forward Ed    schedule 26.05.2016