2012-06-20 22 views
6

Vấn đề định nghĩa:ROW() chức năng cư xử khác nhau bên trong SUM() và SUMPRODUCT()

Nhập bất kỳ số lượng trong tế bào A1. Bây giờ hãy thử các công thức sau ở bất kỳ đâu trên hàng đầu tiên.

=SUM(INDIRECT("A"&ROW())) 

=SUMPRODUCT(INDIRECT("A"&ROW())) 

Công thức đầu tiên đánh giá, điều thứ hai đưa ra một lỗi #VALUE. Điều này là do chức năng ROW() hoạt động khác nhau bên trong SUMPRODUCT().

Trong công thức đầu tiên, ROW() trả về 1. Trong công thức thứ hai, hàng trả về {1} (mảng có độ dài một chiều), mặc dù công thức chưa được nhập dưới dạng công thức CSE.

Tại sao điều này lại xảy ra?

nền

tôi cần phải đánh giá một công thức của các loại

=SUMPRODUCT(INDIRECT(*range formed by concatenation and using ROW()*)>1) 

này đang làm việc ra một lỗi. Như một giải pháp cho vấn đề này, bây giờ tôi tính toán ROW() trong một ô khác (trong cùng một hàng, rõ ràng) và nối nó bên trong INDIRECT() của tôi. Ngoài ra, tôi cũng đã cố gắng đóng gói nó bên trong một hàm tổng hợp, như SUM(ROW()) và cũng hoạt động như vậy.

Tôi chắc chắn sẽ đánh giá cao nếu ai đó có thể giải thích (hoặc chỉ cho tôi tài nguyên có thể giải thích) tại sao ROW() trả về một mảng bên trong SUMPRODUCT() mà không cần nhập CSE.

Trả lời

6

Câu hỏi thú vị. Có những vấn đề tinh tế ở đây mà tôi chưa thấy tài liệu.

Có vẻ như INDIRECT("A"&ROW()) trả về một mảng bao gồm một phần tử tham chiếu đến một ô - không phải là giá trị trong ô đó. Nhiều hàm không thể giải quyết loại dữ liệu này một cách chính xác nhưng một vài hàm như N và T có thể "dereference" mảng và trả về giá trị cơ bản.

Hãy trường hợp này, nơi có hai yếu tố trong mảng:

=SUM(N(INDIRECT("A"&ROW(1:2)))) 

này trả A1 + A2 khi mảng vào nhưng nó chỉ trả về A1 khi bước vào bình thường. Tuy nhiên thay đổi ROW (1: 2) thành {1; 2} trong công thức này trả về kết quả chính xác khi được nhập bình thường. Công thức SUMPRODUCT tương đương trả về A1 + A2 cho dù mảng được nhập hay không.

Điều này có thể liên quan đến cách đối số được đăng ký trong hàm. Theo http://msdn.microsoft.com/en-us/library/bb687900.aspx, về cơ bản có hai phương pháp để đăng ký đối số chức năng để xử lý các loại dữ liệu Excel:

Loại R/U: "Giá trị, mảng và tham chiếu phạm vi".

Loại P/Q: "Excel chuyển đổi tham chiếu ô đơn thành giá trị đơn giản và tham chiếu nhiều ô thành mảng khi chuẩn bị các đối số này".

Đối số SUM có vẻ phù hợp với loại R/U trong khi đối số SUMPRODUCT hoạt động như loại P/Q. Mảng-nhập công thức SUM ở trên buộc đối số tham chiếu phạm vi trong ROW được đánh giá dưới dạng mảng trong khi điều này xảy ra tự động với SUMPRODUCT.

Cập nhật

Sau một chút điều tra thêm, thì đây là bằng chứng thêm rằng có thể ủng hộ lý thuyết này. Dựa vào liên kết trong các bình luận, công thức = SUM ((A1, A2)) cung cấp cho các giá trị tương tự như:

?executeexcel4macro("CALL(""Xlcall32"",""Excel4"",""2JRJR"",4,,1,(!R1C1,!R2C1))") 

Đăng ký đối số cuối cùng as type P bằng cách thay đổi 2JRJR-2JRJP đưa ra một lỗi trong trường hợp này nhưng không cho phép phạm vi khu vực đơn lẻ như !R1C1:!R2C1. Mặt khác, việc thay đổi 4 (xlfsum) thành 228 (xlfsumproduct) chỉ cho phép tham chiếu vùng đơn theo cách được gọi giống như SUMPRODUCT.

+0

+1 nghiên cứu thú vị! –

+0

+1 Đây chính xác là những gì tôi cần. Khả năng 'dereferencing' của các hàm 'N()' và 'T()' làm tôi ngạc nhiên. Trong thực tế, trong công thức '= SUMPRODUCT (N (INDIRECT (" A "& ROW())))', hàm 'N()' thực sự giải quyết lỗi #VALUE (như đã thấy trong Công thức đánh giá, Excel 2003). Điều này là cực kỳ tốt để biết. Ngoài ra thông tin về các kiểu đối số R/U và P/Q dường như là một lời giải thích tốt. Việc xử lý các phần tử 'xlTypeNil' cho các kiểu P/Q có vẻ phù hợp với hành vi của' SUMPRODUCT() '. Cảm ơn một câu trả lời tuyệt vời. Sẽ không bao giờ biết Google làm gì. Xứng đáng một +10 !! – playercharlie

+0

Vui mừng điều này đã giúp - Laurent Longre đã tìm ra hành vi này ban đầu và cho thấy cách bạn có thể sử dụng hàm CALL với tham chiếu đến xlcall.h cho các hàm trang tính: http://www.cpearson.com/excel/Call.htm. Trong VBA, điều này vẫn có thể được truy cập thông qua: 'ExecuteExcel4Macro'. –

2

Khi ROW() trả về một mảng, hãy sử dụng INDEX để lấy phần tử thứ nhất.

Bạn ví dụ sau đó trở thành: =SUMPRODUCT(INDIRECT("A"&INDEX(ROW(),1)))

+0

Cảm ơn câu trả lời. Tôi đã sử dụng hàm 'SUM()' thay cho hàm 'INDEX()' và gặp vấn đề. Tuy nhiên, tôi đang tìm kiếm một lời giải thích là tại sao tôi cần phải làm điều này. – playercharlie

+0

Đây là câu trả lời hay nhất cho tôi. Việc sử dụng INDEX() trên mảng do ROW() được sử dụng bên trong SUMPRODUCT() là hoàn hảo! Nếu biến động là tất cả về tính toán lại, nó sẽ không làm phiền tôi rất nhiều bởi vì máy tính là nhanh hơn nhiều bây giờ. Có rất nhiều gián tiếp và bù đắp được sử dụng trên sổ làm việc của tôi và tôi OK với lên đến 1 giây chậm trễ tính toán lại. Vì vậy, nếu tôi cần sử dụng ROW() bên trong hàm SUMPRODUCT(), thì hàm INDEX() là hàm trợ giúp phải! Cảm ơn bạn rất nhiều SeanC –

+0

Ồ, và cảm ơn mẹo SUM() tự trả lời bởi OP. Nó rút ngắn công thức, và tôi thích loại ngắn hơn. Tôi tự hỏi nếu một trong số họ là nhanh hơn. Có lẽ SUM() nhanh hơn vì nó không dễ bay hơi? –

1

Tôi không nghĩ ROW() cư xử khác nhau ở đây, nó sẽ trả về một mảng trong cả hai trường hợp. Tôi cho rằng SUM và SUMPRODUCT xử lý mảng đó khác nhau - không chắc chắn tại sao.

Nhiều chức năng hoặc kết hợp chúng trả về mảng - bạn không cần CTRL + SHIFT + ENTER để thực hiện điều đó, bạn chỉ cần CSE trong nhiều trường hợp để xử lý các mảng được tạo.

Tôi chỉ sẽ sử dụng INDEX thay TIẾP (mà cũng có lợi cho bạn bằng cách tránh một chức năng không ổn định), ví dụ:

=SUMPRODUCT(INDEX(A:A,ROW()))

....mở rộng đến phạm vi của bạn công thức này sẽ đếm số lượng các giá trị> 1 trong một phạm vi trong cột A trong đó x xác định hàng đầu và y hàng cuối

=COUNTIF(INDEX(A:A,x):INDEX(A:A,y),">1")

x và y có thể được tính bằng công thức

bạn có thể sử dụng SUMPRODUCT hoặc COUNTIFS theo cách tương tự nếu có nhiều điều kiện để thêm

+0

Cảm ơn câu trả lời. Tôi đã sử dụng hàm 'SUM()' xung quanh hàm 'ROW()' và gặp vấn đề. Ngoài ra, đối với vấn đề cụ thể của tôi, tôi đã phải sử dụng hàm 'INDIRECT()', vì các tham chiếu ô đã được tính toán ở nơi khác !. Bạn dường như đã có nó ngay khi bạn nói CSE chỉ thay đổi việc xử lý mảng. @lori_m có một câu trả lời tuyệt vời về lý do tại sao 'SUM()' và 'SUMPRODUCT()' xử lý các mảng khác nhau. – playercharlie

Các vấn đề liên quan