2011-11-04 19 views
8

Tôi đang tìm cách tính một số ngẫu nhiên một lần trong Excel. Vì vậy, nó tính lần đầu tiên được gọi, nhưng sau đó nó không thay đổi sau đó. Ví dụ, nếu tôi có một cái gì đó như thế này trong B1 RANDONCE(A1), thì lần đầu tiên tôi đặt một giá trị trong A1 nó sẽ tính một giá trị ngẫu nhiên nhưng sau đó nó sẽ không thay đổi một lần nữa. Hoặc ít nhất là cho đến khi tôi thay đổi A1 lần nữa.Tính số ngẫu nhiên tĩnh (tính toán nó một lần) trong Excel

Tôi muốn thực hiện việc này mà không cần sao chép B1 theo cách thủ công để chuyển từ công thức sang giá trị như được mô tả here. Sử dụng macro là tốt.

+1

Giá trị cần phải giữ "cố định" trong bao lâu? Chỉ trong một phiên, hoặc sau khi lưu, vv? –

+0

Nếu bạn hài lòng với một giá trị không thực sự 'ngẫu nhiên', chỉ mờ đục, bạn có thể sử dụng một cái gì đó được liên kết từ http://stackoverflow.com/questions/3498356/md5-hash-function-in-excel để tính giá trị băm của giá trị trong 'A1'. – AakashM

+0

Có vẻ như bạn muốn một sự kiện. Tôi đã thêm một câu trả lời dưới đây. Lưu ý rằng bạn có thể gán cho B1 giá trị của nó (từ một công thức) trong một bước trong VBA, do đó bạn không cần phải làm như nó được đăng trong liên kết mà bạn đã thêm vào. – aevanko

Trả lời

3

Bạn cần một UDF với bộ nhớ, vì vậy nó biết nếu các tế bào đã thay đổi

UDF này sẽ trả về một giá trị ngẫu nhiên mới khi giới thiệu đến gọi thay đổi, nếu không trả về giá trị ngẫu nhiên cuối cùng (tức là không thay đổi)
Cũng trả lại trống nếu ô nguồn trống (có thể hoặc không phải là thứ bạn yêu cầu?)

Lưu ý: có vấn đề là giá trị Static bị mất khi đóng trang tính, vì vậy giá trị sẽ thay đổi mỗi lần trang tính được mở.

Function randonce(r As Range) 
    Static trigger As Variant 
    Static v As Double 
    If r <> trigger Then 
     v = Rnd 
     trigger = r 
    End If 
    If Len(r) <> 0 Then 
     randonce = v 
    Else 
     randonce = vbNullString 
    End If 
End Function 
+0

Cảm ơn bạn đã trả lời câu hỏi này, @ChrisNeilsen! Nó chỉ cần một vài tinh chỉnh nhỏ để trở thành một giải pháp tất cả-trong-một. ** Dòng đầu tiên: ** 'Hàm RandOnce (Thấp Như Dài, Cao Như Dài, r Như Phạm Vi) Như Dài' ** Thay Đổi ** 'v = Rnd' ** thành **' v = Int (Rnd * (Cao + 1 - Thấp)) + Thấp' và ** thêm 'Ngẫu nhiên' ** sau khi khai báo để đảm bảo RNG được đặt lại. – TesseractE

3

Bạn có thể tạo một UDF (Chức năng người dùng định nghĩa):

Public Function Rand_once(ByVal r As Range) 
    Rand_once = Rnd 
End Function 

Trong ô nơi bạn muốn kết quả, bạn có thể đặt:

=Rand_once(A1) 

Giá trị sẽ thay đổi (trên thực tế, được tính toán lại) chỉ khi giá trị nguồn thay đổi (aka A1).

+2

-1 Điều này sẽ thay đổi giá trị nếu trang tính có tính toán lại đầy đủ (ví dụ: nhấn ctrl-alt-F9) –

+0

Điều này không được OP trước và tôi nghĩ rằng điều này sẽ đủ cung cấp thông tin mà ông đã cung cấp. – JMax

+2

Tôi không đồng ý. Tôi nghĩ "nhưng sau đó nó sẽ không thay đổi một lần nữa" không bao gồm thay đổi trên recalc đầy đủ. –

1

Điều này rõ ràng sẽ không phải là giải pháp tốt nhất nếu bạn có để theo dõi nhiều tế bào, nhưng nếu đó là chỉ A1 bạn cần phải theo dõi những thay đổi, bạn có thể sử dụng một sự kiện để làm chức năng của bạn trong B1, sau đó ở cuối, gán cho nó giá trị đã được đưa ra. Tôi thấy đây là giải pháp đơn giản nhất và nó hoạt động như bạn yêu cầu.

Ví dụ:

Private Sub Worksheet_Change(ByVal Target As Range) 

If Target.Address = "$A$1" Then 
    With Cells(1, 2) 
     .Value = "=rand()" 'or whatever 
     .Value = .Value 
    End With 
End If 

End Sub 
+0

Nếu bạn phải theo dõi nhiều ô, bạn có thể sử dụng 'Giao lộ' để làm cho nó dễ đọc hơn. Tuy nhiên, tôi thấy giải pháp này khá tuyệt vì nó rõ ràng sẽ không thay đổi giá trị (bất cứ khi nào Full Recalc hay như vậy, hãy xem cuộc tranh luận với Chris bên dưới câu trả lời của tôi) cho đến khi 'A1' thay đổi (vì vậy tôi nghĩ rằng điều này sẽ là +1 :)) – JMax

4

Tôi nghĩ rằng tôi có một cách dễ dàng hơn để làm điều này. Hoàn thành bảng tính của bạn, sau đó áp dụng hàm = RANDBETWEEN cho cột số đó. Sau đó, làm điều này:

  1. Sao chép kết quả từ cột đó.
  2. Đánh dấu cột và chọn "dán đặc biệt" và chọn "giá trị".

Bây giờ bạn có các giá trị được tạo gần đây nhất và chúng tĩnh.

2

Bạn cũng có thể sử dụng tham chiếu vòng tròn để tạo "công tắc bật" thuần túy theo công thức, cho phép người dùng tính toán số ngẫu nhiên và sau đó tắt tính toán lại. Turn off circular reference warnings, và sau đó đặt công thức này ở ô B3:

=IF($B$1="YES",RAND(),B3) 

Nếu ô B1 chứa "YES", B3 sẽ tạo ra một số ngẫu nhiên mới với mỗi tính toán lại bảng tính; nếu B1 chứa bất kỳ giá trị nào khác, giá trị hiện tại của B3 sẽ được giữ lại.

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