#excel #vba
#excel #vba
Вопрос:
Я очень новичок в программировании и просто хочу поблагодарить всех на этом сайте, кто уже так мне помог.
Я пытаюсь создать генератор случайного времени, который будет генерировать случайное время в пределах диапазона, указанного пользователем. В настоящее время я использую WorksheetFunction.Команда Randbetween, которая эффективно генерирует случайное время, однако оно не находится в пределах указанного диапазона. Этот код является частью более крупной пользовательской формы, которая выполняет аналогичные функции. Остальная часть кода работает нормально (ish).
Мой вопрос: что мне нужно добавить в мою строку кода, чтобы заставить ее эффективно генерировать время в указанном диапазоне? Мне также нужно убедиться, что он работает в 24-часовом формате «ЧЧ: ММ: СС» или «ЧЧ: ММ».
Я пробовал использовать Round и WorksheetFunction.Randbetween
Private Sub Generate_Data_Button_Click()
Dim emptyRow As Long
Randomize
'Make Data Active
Sheet1.Activate
'Determine emptyRow
emptyRow = WorksheetFunction.CountA(Range("A:A")) 1
'Transfer information to template
Cells(emptyRow, 4).Value = WorksheetFunction.Randbetween (start_time_textbox.value, end_time_textbox.value) Rnd()
'Format cell on template
Cells(emptyRow, 4).NumberFormat = "hh:mm:ss"
End Sub
Комментарии:
1.
RANDBETWEEN
возвращает целое число. 24 часа эквивалентны 1, поэтому по определению между вашим временем начала и временем окончания нет случайного целого числа — оба находятся между 0 и 1. Вы можете умножить каждое из них на 86400, чтобы получить соответствующее время в секундах, использовать секундыRANDBETWEEN
, а затем разделить результат на 86400, чтобы получить время.2. Потрясающе! Большое спасибо за ответ. Это имеет смысл. Я все еще зацикливаюсь на том, как он генерирует случайное время, но не внутри предоставленного мной диапазона. Например, если я введу 08:00 в качестве времени начала и 10:00 в качестве времени окончания, он будет выводить все с 02:30 до 23:59.
Ответ №1:
Метод Randomize / Rnd
После Randomize
Rnd
этого генерирует псевдослучайное десятичное число от нуля до единицы при каждом его вызове. Если ваши времена являются значениями полного времени (например, 23:59:45), преобразуйте строки, возвращаемые полями ввода, используя преобразование строки TimeValue в double, и используйте некоторую математику, чтобы принудительно ввести значения Rnd внутри времени начала и остановки.
Private Sub Generate_Data_Button_Click()
Dim emptyRow As Long, tstart As Double, tend As Double
'convert string times from input to true time as double
tstart = TimeValue(start_time_textbox.Value)
tend = TimeValue(end_time_textbox.Value)
Randomize
'Make Data Active
With Worksheets("Data")
'Determine emptyRow in COLUMN D
emptyRow = .Cells(.Rows.Count, "D").End(xlUp).Row 1
'Transfer information to template
.Cells(emptyRow, "D").Value = (tend - tstart) * Rnd() tstart
'Format cell on template
.Cells(emptyRow, "D").NumberFormat = "hh:mm:ss"
End With
End Sub
Метод случайного переключения
Чтобы использовать функцию Randbetween рабочего листа, вам нужно преобразовать время начала и окончания в длинные целые числа, представляющие количество секунд, прошедших с полуночи, а затем рандомизировать между ними. Возьмите результат и преобразуйте его обратно в значение времени, уменьшив его на количество секунд в день.
Private Sub Generate_Data_Button_Click2()
Dim emptyRow As Long, tstart As Long, tend As Long, siad As Long
siad = 86400 'seconds in a day
'convert string times from input to seconds in a day as Long Integer
tstart = TimeValue(start_time_textbox.Value) * siad
tend = TimeValue(end_time_textbox.Value) * siad
'Make Data Active
With Worksheets("Data")
'Determine emptyRow in COLUMN D
emptyRow = .Cells(.Rows.Count, "D").End(xlUp).Row 1
'Transfer information to template
.Cells(emptyRow, "D").Value = Application.RandBetween(tstart, tend) / siad
'Format cell on template
.Cells(emptyRow, "D").NumberFormat = "hh:mm:ss"
End With
End Sub
Комментарии:
1. Еще раз спасибо всем, кто помог мне решить эту проблему. Я занимаюсь этим меньше недели, так что это определенно было огромной помощью! Ваше здоровье!
Ответ №2:
Вы можете сделать это как UDF. Идея состоит в том, чтобы сгенерировать случайную минуту для смещения от Time1.
Сначала преобразуйте часы и минуты обоих периодов в минуты как единицу измерения.
Затем, основываясь на разнице в минутах, сгенерируйте случайные минуты, используя RandBetween
, вычтите базовое время, затем добавьте эти случайные минуты к базовому времени (в минутах).
Function RandomTimeBetween(FromTime As Range, ToTime As Range) As Date
Dim Time1 As Date, Time2 As Date, Minutes As Integer
Time1 = CDate(FromTime.Value)
Time2 = CDate(ToTime.Value)
Minutes = Hour(Time1) * 60 Minute(Time1) ' Base time in minutes
' Find the random offset time between them, deduct the base time
Minutes = WorksheetFunction.RandBetween(Minutes, Hour(Time2) * 60 Minute(Time2)) - Minutes
RandomTimeBetween = Time1 TimeSerial(0, Minutes, 0)
End Function
Если вы хотите выполнить рандомизацию с точностью до секунд, вам необходимо изменить значение ниже, поскольку переполнение может произойти в TimeSerial:
Function RandomTimeBetween(FromTime As Range, ToTime As Range) As Date
Dim Time1 As Date, Time2 As Date, Seconds As Long
Time1 = CDate(FromTime.Value)
Time2 = CDate(ToTime.Value)
Seconds = Hour(Time1) * 3600 Minute(Time1) * 60 Second(Time1) ' Base time in seconds
' Find the random offset time between them, deduct the base time
Seconds = WorksheetFunction.RandBetween(Seconds, Hour(Time2) * 3600 Minute(Time2) * 60 Second(Time2)) - Seconds
RandomTimeBetween = Time1 TimeSerial(Seconds 3600, Seconds 60, Seconds Mod 60)
End Function