나눔터  
  HOME > 나눔터 > 묻고답하기 > 엑셀
엑셀
엑셀에 대한 질문과 답변을 올려주세요. 단, 취지에 맞지 않는 글은 운영자가 삭제합니다.
 "000 님, 도와주세요", "부탁 드립니다.", "급합니다!" 등과 같이 막연한 제목을 달지 말아주세요.
[필독] 빠르고 정확한 답변을 얻는 16가지 Tip !
[필독] 저작권법 개정에 따른 이용안내
작성자:  

 코알라 (sis0351)

추천:  2
파일:     난수-오튜.xlsx (11.3KB) 조회:  3296
제목:   [RE]vba 난수들의 합이 일정범위에 들어가도록 하고싶습니다.
     
 
 - 엑셀 버전(2007)

* 아래줄에 질문을 작성하세요 >>

안녕하세요 초보 vbaer 입니다.
검색만 1개월짼데 정확하게 구현이 안되는 부분이 있어서 문의좀 드릴까 댓글 남깁니다.
예를 들어서
a의 값은 500~530사이의 숫자이고
b의 값은 20~40
c= 30~50
d= 120~140
e= 140~160
f= 110~130
g= 50~70
h= 20~40 사이의 값이고
b~h 의 값은 모두 난수로 발생을 시킬것이고
a=b+c+d+e+f+g+h의 값입니다.
모든 수는 소숫점 1자리까지구요.
이 조건을 만족하는 코드를 짜고 싶은데 일하면서 배우면서 검색하면서 하려니 도무지 답이 않나와서 문의 드립니다.
답변 부탁드립니다. 대박나면 피자한판 보내드리겠습니다.
==============[이정열님 글에 대한 답변입니다]==============
 
[불량 게시물 신고]  
조삿갓VBA 코드 짜고 있는데 코알라님께서 함수로 답을 주셨네요?
문제는 a=b+c+d+e+f+g+h라는데
각각 요소의 최솟값끼리 더한 결과는 490이고
최댓값끼리 더한 결과는 630이라는 게 문제네요.
따라서 단순히 난수 7개를 각 범위별로 발생시키면
a값이 범위 밖의 값이 나올 수 있다는 것이지요.
결국 VBA가 더 편한 해결 방법이네요.
09-15 (21:17)
삭제 ■신고
조삿갓Function RndNumber(ByRef RndElement() As Double) As Double
    Const most = 530
    Const least = 500
    Dim i As Integer
    Dim a As Double
    Dim r As Integer
    Dim rBase As Variant
    Randomize Timer
    rBase = Array(20, 30, 120, 140, 110, 50, 20)
    Do
        a = 0
        For i = 0 To 6
            r = Int(Rnd() * 200)
            RndElement(i) = r / 10 + rBase(i)
            a = a + RndElement(i)
        Next i
    Loop Until a >= least And a <= most
    RndNumber = a
End Function
09-15 (21:49)
삭제 ■신고
조삿갓위와 같이 하면 되겠습니다.
함수로 작성했으니 필요한 곳에서 이 함수를 호출하면 됩니다.

a의 값은 함수 결과 값으로
 그리고 각 요소인 b~h는 배열로 반환합니다.
   (이런 성격의 프로그램은 배열을 사용하는 게 효율적이니까요)

예를 들면 다음과 같이 사용하시면 됩니다
Sub test()
     Dim a As Double
     Dim i As Integer
     Dim e(6) As Double
     a = RndNumber(e)
     Debug.Print "a="; a
     For i = 0 To 6
         Debug.Print "e(";i;")="; e(i)
     Next i
 End Sub
09-15 (21:49)
삭제 ■신고
조삿갓참고로

  r = Int(Rnd() * 200)
  RndElement(i) = r / 10 + rBase(i)

두 줄을

  RndElement(i) = Int(Rnd() * 200) / 10 + rBase(i)

이렇게 해도 될 것 같은데
실제로는 이진수 변환 오차 때문에
소수 첫째 자리로 떨어지지 않고 무한소수가 나옵니다.
09-15 (21:57)
삭제 ■신고
코알라RndElement(i) = CInt(Rnd() * 200) / 10 + rBase(i)09-15 (22:59)
삭제 ■신고
조삿갓아하, 형변환 함수에서는 무한소수 오차가 발생하지 않네요.

그런데, Int(3.5) = 3 인데 Int(3.5) = 4 로 반올림한다는 차이가 또 신경이 쓰입니다만, 실험 결과로는 오히려 이게 질문자의 의도와 맞는 프로그램이 될 것 같네요.

수학적으로 Rnd 함수는 0 이상 1 미만의 난수를 발생하므로
 원래의 코드대로 하면 b 값은 20.0~39.9까지만 나오지요. 그런데 반올림해 버리니까 가끔씩 40이 나옵니다. 물론 확률이 공평하지 않지만, 또 a의 범위 제한 때문에 최솟값이나 최댓값이 배제되고 다시 루프를 도는 현상이 발생하니까 대충 실용상 지장은 없을 것 같습니다.

코알라님 감사합니다. 항상 많이 배우네요.
09-16 (00:37)
삭제 ■신고
조삿갓공평한 확률 만들기

20.0 ~ 39.9
    RndElement(i) = CInt(Rnd() * 200 - 0.5) / 10 + rBase(i)

 20.0 ~ 40.0
    RndElement(i) = CInt(Rnd() * 201 - 0.5) / 10 + rBase(i)
09-16 (00:42)
삭제 ■신고
        
  

작성일 : 2017-09-15(20:57)
최종수정일 : 2017-09-15(20:57)
 


 ◎ 관련글

  제 목   작성자   날짜
vba 난수들의 합이 일정범위에 들어가도록 하고싶습니다. 이정열 2017-09-15
[RE]vba 난수들의 합이 일정범위에 들어가도록 하고싶습니다. 코알라 2017-09-15
[RE]vba 난수들의 합이 일정범위에 들어가도록 하고싶습니다. 이정열 2017-09-16
질문을 구체적이고 정확하게 하셔야 원하는 답변을 빨리 얻을 수 있습니다. 조삿갓 2017-09-16