2015-04-23 15 views
5

Tôi đã nhận thấy rằng UDF của tôi tính toán lại bất cứ khi nào tôi xóa các ô. Điều này gây ra sự chậm trễ lớn khi xóa toàn bộ các cột, bởi vì UDF được gọi cho mỗi và mọi ô được sử dụng. Vì vậy nếu bạn đang sử dụng 1000 UDFS, thì việc xóa một cột hoặc ô sẽ gọi nó là 1000 lần.Cần dừng UDF tính toán lại khi các ô không liên quan bị xóa

Bằng một ví dụ, đặt UDF sau đây trong một mô-đun, sau đó gọi nó từ bảng tính một loạt các lần với = HelloWorld()

Function HelloWorld() 
HelloWorld = "HelloWorld" 
Debug.Print Now() 
End Function 

Sau đó xóa liên tiếp. Nếu trải nghiệm của bạn giống như của tôi, bạn sẽ thấy nó được gọi một lần cho mỗi trường hợp sử dụng.

Bất cứ ai cũng có bất kỳ ý tưởng nào cho dù hành vi này có thể dừng lại không? Tôi cũng muốn được quan tâm tại sao nó nên được gọi. Có vẻ như một lỗ hổng trong cây phụ thuộc của Excel với tôi, nhưng cũng có thể là một lý do chính đáng.

Edit: Sau khi thử nghiệm, tôi đã tìm thấy nhiều hành động kích hoạt UDFs:

  1. Bất kỳ thay đổi số lượng cột rằng một ListObject (ví dụ Excel Bảng) kéo dài qua thay đổi kích thước (nhưng không hàng). Ngay cả khi bản thân UDF không có trong ListObject có liên quan, hoặc thực tế là trong bất kỳ bất kỳ ListObject nào cả.
    1. Thêm ô hoặc cột mới vào bất kỳ vị trí nào trong trang tính (nhưng không phải hàng).

Lưu ý rằng Manual Calc Mode không phải là một lựa chọn trên nhiều mặt trận. Thứ nhất, vì nó là một ứng dụng cấp thiết lập, nó chỉ đơn giản là trình bày một nguy cơ quá lớn mà ai đó sẽ sử dụng đầu ra của bất kỳ một trong các bảng tính mà họ xảy ra đã mở mà không nhận ra họ đang ở chế độ tính toán thủ công. Thứ hai, tôi không thực sự thiết kế một bảng tính cụ thể mà là viết một cuốn sách về cách những người không phát triển có thể sử dụng các mã có sẵn như UDF để làm những thứ có thể vượt ra ngoài chúng. Ví dụ bao gồm tự động ghép hoặc tách văn bản hoặc tìm kiếm chính xác kết hợp nhị phân UDF mà Charles Williams phác thảo tại https://fastexcel.wordpress.com/2011/07/22/developing-faster-lookups-part-2-how-to-build-a-faster-vba-lookup/ (Và vâng, tôi cung cấp cho họ nhiều cảnh báo rằng thường là giải pháp dựa trên công thức gốc sẽ hoạt động tốt hơn UDF. các chủ đề tôi đã tham chiếu ở trên, các chức năng viết cẩn thận có thể hoạt động tốt).

Tôi không biết người dùng sẽ sử dụng những điều này như thế nào.

Khi không có giải pháp lập trình, có vẻ như tôi sẽ chỉ ra trong cuốn sách mà người dùng có thể gặp phải sự chậm trễ đáng kể khi thêm hoặc xóa ô hoặc thay đổi kích thước ListObject nếu họ có UDFS chuyên sâu về tài nguyên. Ngay cả khi những UDF đó được viết một cách hiệu quả.

+0

dicks blog đáp ứng stackoverflow :) Câu hỏi thú vị khi tôi xác nhận điều này giữ, mặc dù UDF của bạn không có dải ô liên quan, hàm volatile kết hợp với nó hoặc 'Application.Volatile'. Một nội dung đơn giản rõ ràng không kích hoạt UDF, một hàng xóa. Tôi sẽ chờ một bài đăng từ Charles Williams với sự quan tâm. – brettdj

+0

Bạn đã thử đặt phương thức tính toán excel thành Manual. Chế độ tính toán thủ công nghĩa là Excel sẽ chỉ tính toán lại tất cả các sổ làm việc đang mở khi bạn yêu cầu bằng cách nhấn F9 hoặc Ctrl-Alt-F9 hoặc khi bạn Lưu sổ làm việc. Đối với sổ làm việc mất hơn một phần nhỏ của giây để tính lại thì thường là tốt hơn để đặt Tính toán thành Thủ công. – izzymo

+0

Xin chào Izzymo. Tôi chỉ rõ Chế độ Calc bằng tay bất cứ khi nào tôi có thể, dựa trên những điều sau đây: * Khả năng đầu ra được sử dụng mà không có mô hình được làm mới. Tôi thường không phải là người dùng duy nhất. * Nếu sổ làm việc đầu tiên bạn mở trong ngày xảy ra là ngày được lưu trong chế độ Tính toán thủ công thì tất cả các sổ làm việc khác mà bạn mở trong ngày cũng sẽ được chuyển sang chế độ Tính toán thủ công. Có thể bạn thậm chí không biết. Chế độ calc thường được sử dụng để che dấu các triệu chứng của bảng tính được thiết kế kém. Không phải trong mọi trường hợp, và tôi không nói tất cả đều xấu. Hầu như chỉ có thể tránh được. – jeffreyweir

Trả lời

0

Thật không may, tôi không tin rằng có thể ngăn không cho UDF tính toán lại khi các ô "không liên quan" bị xóa. Lý do cho điều này là đối số được truyền cho UDF thực tế là đối tượng Range (không chỉ giá trị trong (các) ô). Việc xóa các ô "không có liên quan" có thể thực sự sửa đổi Range.

Ví dụ, người dùng có thể viết loại UDF:

Function func1(rng) 
    func1 = rng.Address & " (" & Format(Now, "hh:mm:ss") & ")" 
End Function 

Phải thừa nhận rằng, đây không phải là cách tiếp cận phổ biến (và đề nghị) để viết một UDF. Nó thường phụ thuộc vào nội dung (giá trị) và không phải là vùng chứa (dải ô).

Ở đây tôi chỉ trả về địa chỉ của đối số. Tôi cũng nối thêm một dấu thời gian để báo hiệu khi UDF được tính toán lại. Nếu bạn xóa bất kỳ cột nào trên trang tính, tất cả các ô có UDF này sẽ được tính toán lại. Nhưng không phải nếu bạn chèn một cột, để lại các ô bên phải (của cột mới này) không thay đổi và với giá trị sai (địa chỉ ô). Các kết quả giống nhau với việc chèn/xóa các hàng. Kỳ lạ thay, chèn một ô đơn lẻ sẽ buộc tính toán lại tất cả các UDF.

Tôi đã cố gắng xóa "phụ thuộc" trên Range. Nhưng hành vi cũng giống nhau ngay cả khi đối số UDF được gõ as double (thay vì để nó như là một biến thể như trong ví dụ của tôi).

Như bạn đã giải thích, việc xóa một cột sẽ buộc UDF được tính toán lại. Điều này có ý nghĩa bởi vì một UDF có thể phụ thuộc vào đối số Range. Đây là một thiết kế thông minh cho một UDF là một vấn đề khác.

+0

bình luận của bạn ** Lý do cho điều này là đối số được chuyển đến UDF thực ra là một Phạm vi **: hàm đơn giản của tôi không truyền bất kỳ đối số nào cả. Vì vậy, tôi không thấy lý do tại sao Excel sẽ cần phải tính toán lại nó. – jeffreyweir

+0

@jeffreyweir: Đúng vậy. Những gì tôi có nghĩa là một UDF có thể phụ thuộc vào một đối số 'Phạm vi'. Dường như các nhà phát triển đã chọn (không may) cập nhật tất cả các UDF thay vì chỉ cập nhật những người có các đối số 'Phạm vi' (tức lànhững người có thể yêu cầu cập nhật sau khi xóa cột). – bouvierr

5

Chèn hoặc xóa một hàng hoặc cột hoặc ô sẽ luôn kích hoạt một lần lặp lại ở chế độ tự động. (Bạn có thể kiểm tra điều này bằng cách thêm = NOW() vào một sổ làm việc trống và chèn hoặc xóa mọi thứ)


Câu hỏi phải là trường hợp (bất ngờ) gắn cờ ô bị bẩn để được xếp lại. Có một (có thể không đầy đủ) danh sách những điều như vậy ở

Hình như tôi cần phải thêm một số lời về VBA UDFs (chưa được thử nghiệm XLL UDFs
- họ có thể hành xử khác nhau kể từ khi họ được đăng ký theo một cách khác tới VBA UDFs)

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