2016-08-04 10 views
7

Chúng tôi thường sử dụng các từ ngữ: Cells(i, 1), Cells(i, "A"), hoặc Range("A" & i) để chỉ một tế bào động trong VBA, nhưng tôi tìm thấy sau kỳ lạ mã cũng hoạt động:Có phải những cách mới lạ này [và có thể là cách tốt nhất?] Để chỉ một ô động trong VBA?

Sub Test1() 
For i = 1 To 10000 
    Range("A1")(i) = i 
Next 
End Sub 

tôi cũng tìm thấy shortcut ký hiệu sử dụng các dấu ngoặc vuông [] để tham chiếu đến một ô (Có, tôi biết rằng một phương pháp viết tắt thể hiện lệnh EVALUATE) cũng có thể được sử dụng ở đây như các mã sau đây

Sub Test2() 
For i = 1 To 10000 
    [A1].Resize(1000, 1)(i) = i 
Next 
End Sub 

hoặc

Sub Test3() 
For i = 1 To 10000 
    [A1].Offset(i - 1) = i 
Next 
End Sub 

Đó là trái với niềm tin phổ biến rằng dấu ngoặc vuông chỉ có thể tham khảo cố định dãy với ký hiệu phím tắt. Tôi đã kiểm tra tất cả chúng và chúng trả về cùng một kết quả đầu ra.

Thành thật mà nói, tôi chưa bao giờ nghĩ rằng ba biểu thức này từng tồn tại, vì vậy tôi đoán chúng có thể mới. Có đúng không?


Tôi không chỉ tìm thấy chúng, tôi còn kiểm tra chúng để xem cái nào là tốt nhất. Bởi tốt nhất tôi có nghĩa là trong hiệu suất của họ bằng cách sử dụng kiểm tra thời gian. Tôi đã thử nghiệm những điều khoản:

  1. Cells(i, 1) = Rnd
  2. Range("A" & i) = Rnd
  3. Cells(i, "A") = Rnd
  4. Range("A1")(i) = Rnd
  5. [A1].Resize(1000, 1)(i) = Rnd
  6. [A1].Offset(i - 1) = Rnd

như sau đang

Sub Test() 
Dim i As Long 

Randomize 
For i = 1 To 1000  'I also tested them with 10,000 loops 
    'Put the expression here 
Next 
End Sub 

tôi đắc thời hạn thời gian để hoàn thành trên máy tính của tôi như sau

1,000 loops 
1    2    3    4    5    6 
0.290110725  0.298291317  0.305540433  0.289084126  0.325044276  0.318445433 
0.270974218  0.287950980  0.276009685  0.277133638  0.318741694  0.312968414 
0.277361318  0.274790389  0.273291810  0.275994401  0.311879789  0.312000675 
0.279113453  0.275501647  0.275247422  0.281113426  0.311558662  0.315628943 
0.270359637  0.276440868  0.279950951  0.276444561  0.320118775  0.311556754 
0.270066136  0.281525061  0.273649022  0.276767648  0.311083246  0.311015128 
0.274146235  0.277156933  0.274465750  0.287375210  0.311426416  0.319849274 
0.269184843  0.277200430  0.276525859  0.276931561  0.322461782  0.310902381 
0.271190611  0.283046575  0.280286123  0.275876294  0.312358236  0.313066500 
0.271210909  0.277953463  0.274105173  0.276916590  0.312845710  0.321566549 

Average time 
0.274371809  0.280985766  0.278907223  0.279363746  0.315751859  0.314700005 

10,000 loops 
1    2    3    4    5    6 
1.897854697  1.975970014  2.026380540  1.963044684  2.667340257  2.404596752 
1.893136200  1.958722430  1.997488630  1.957524600  2.412742475  2.364692000 
1.915567238  1.991447404  2.026974359  1.972207855  2.396174991  2.408500400 
1.885336683  1.964379644  2.001175971  1.950138292  2.362537378  2.369196417 
1.889658641  1.959677449  1.998453783  1.984470995  2.372677528  2.366525087 
1.885327819  1.963668734  1.997487505  2.038683070  2.367691027  2.380044796 
1.878379741  1.958654295  2.002764956  2.008183347  2.368766984  2.362091273 
1.894069516  1.960857991  1.994435035  2.031241378  2.377953481  2.367554909 
1.894528017  1.972240515  2.003587552  1.961539277  2.364523191  2.373092790 
1.883387443  1.965169572  1.999893716  1.948455660  2.363346303  2.368680396 


Average time 
1.891724600  1.967078805  2.004864205  1.981548916  2.405375362  2.376497482 

Dựa trên hai kết quả này, mặc dù kết quả là không phân thắng bại để so sánh các biểu thức : Range("A" & i), Cells(i, "A")Range("A1")(i) và cũng để so sánh [A1].Resize(1000, 1)(i)[A1].Offset(i - 1), nó t urned ra hiệu suất nhanh nhất là Cells(i, 1). Điều này có đúng không? Tại sao như vậy? Tôi đoán là trong thời gian chạy VBA luôn sử dụng Cells(i, 1), vì vậy khi mã được biên dịch tất cả các tham chiếu trong các biểu thức khác phải được chuyển thành biểu thức 1 vì tôi tin rằng VBA phải ghi nhớ cả phiên bản được biên dịch của mã và bất kỳ biểu thức nào chúng ta đã sử dụng viết mã của chúng tôi. Nhưng đó chỉ là suy đoán về phía tôi.

+0

Đẹp nhất. Một thử nghiệm liên quan tôi đã thực hiện một vài tháng trở lại trên một vài loại tài liệu tham khảo: [Phạm vi VS tế bào chạy lần] (https://stackoverflow.com/questions/36073943/range-vs-cells-run-times/36073944) – vacip

+0

tôi Xin lỗi ông @ ScottCraner, tôi không nghĩ đó là một sự lừa đảo vì phần đầu tiên có phần mới. Bạn đã xem trước khi đánh dấu câu hỏi của tôi là một sự lừa đảo? –

+0

Bạn có thể đăng các số đo của mình dưới dạng câu trả lời cho câu hỏi đó và hỏi phần đầu tiên trong câu hỏi riêng. – vacip

Trả lời

4

sau kỳ lạ đang

Không thực sự. Mã không kỳ quái.
Vấn đề là, biến số Range là "chế độ xem" cho trang tính chứ không phải hộp cố định có tường bê tông. Bạn hoàn toàn có thể vượt quá giới hạn được xác định ban đầu của Range.

Dòng

Range("A1")(i) = i 

tương đương với

Range("A1").Cells(i).Value = i 

đó là hoàn toàn có thể làm được mặc dù Range("A1") chỉ chứa một tế bào - bạn chỉ là bước ngoài tế bào đó.

Tôi chưa bao giờ nghĩ rằng ba biểu thức này từng tồn tại, vì vậy tôi đoán chúng có thể mới. Có đúng không?

Không, không phải. Họ rất già. Văn phòng lâu đời nhất tôi có trong tay là 2003 và nó hoạt động ở đó, và tôi khá tự tin rằng nó từng làm việc trong Office 95.

Lý do bạn chưa bao giờ nghe về chúng có lẽ là vì không ai sử dụng chúng được cho là một điều tốt. Mặc dù chúng có giá trị từ quan điểm của mô hình đối tượng, nhưng chúng gây nhầm lẫn hơn nhiều cách đơn giản hơn.

nó bật ra hiệu suất nhanh nhất là Cells(i, 1). Điều này có đúng không? Tại sao như vậy?

Tôi chưa bao giờ thử nghiệm (và tôi sẽ không), nhưng hợp lý Cells(i, 1) phải là nhanh nhất vì nó không liên quan đến phân tích chuỗi và/hoặc đánh giá. Có thể cho rằng, tất cả các tùy chọn khác cuối cùng gọi là Cells(i, 1).

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