一个可以自动生成随机区组试验的excel VBA小程序

作者 : admin 本文共3907个字,预计阅读时间需要10分钟 发布时间: 2024-06-9 共3人阅读

        在作物品种区域试验时,通常会采用随机区组试验设计,特制作了一个可以自动生成随机区组试验的小程序excel参数界面如下:

一个可以自动生成随机区组试验的excel VBA小程序插图

参数含义如下:

1、生成新表的名称:程序将新建表格,用于生成随机区组试验。若此处为空,则为系统默认的新建表格名称,若含有名称,则新建表以此名称命名。

2、是否含排区号:若选择“是”,则以“1-1”的形式显示第几排,第几个小区。若选择“否”,则不显示,仅在标题处显示区组名称。

3、区组内品种排列方向:若为“横向”,则表格中在同一行中排列一个区组的不同品种;如选择“纵向”,则表格中在同一列中排列一个区组的不同品种。

4、区组数量:表示需要设置的区组数量,通常为3。

以上图中默认的设置运行代码,显示结果如下:

一个可以自动生成随机区组试验的excel VBA小程序插图(1)

具体实现代码如下:

Sub 生成试验设计()
Dim ws As Worksheet, tg_ws As Worksheet
Dim rng As Range, rng2 As Range
Dim cell As Range, lastcell As Range
Dim pq As String, sn As String, pl As String   'pq即排区号的简称,sn即sheetname的简称,pl即排列的简称
Dim qz_num As Integer
Dim i As Integer, j As Integer, lastRow As Integer
Dim m As Integer, n As Integer
Dim arr As Variant, rngValues As Variant, tmp As Variant
Application.ScreenUpdating = False       '刷新屏幕关闭
Application.DisplayAlerts = False        '警告提示框关闭
'获取初始设置
sn = Range("A2").Value    '新建工作表的名称
pq = Range("A5").Value   '是否包含排区号
pl = Range("A8").Value    '试验设计是横向排列还是纵向排列
qz_num = Range("A11").Value    '区组的数量
'获取品种名称
lastRow = Range("C10000").End(xlUp).Row    '获取品种名称列的最后一行的行号
Set rng = Range("C2:C" & lastRow)
' 新建一个工作表,用于生成随机区组试验设计
Set ws = ThisWorkbook.Sheets.Add
If sn  "" Then
ws.Name = sn       ' 将新工作表的名称设置为"新工作表"
End If
' 将范围内的值存储在数组中
rngValues = rng.Value
ReDim arr(UBound(rngValues)) As Variant
If pq = "否" Then    '没有排区号的情况
Select Case pl
Case "横向"
'输入行标题
For i = 1 To qz_num
ws.Cells(i, 1).Value = "区组" & i
Next
'将品种名称放入对应行排号的单元格中
For j = 1 To qz_num    '对行号循环
' 随机排列数组中的元素
arr = rngValues
Randomize ' 初始化随机数生成器
For m = LBound(arr) To UBound(arr) - 1
n = Int((UBound(arr) - m + 1) * Rnd + m)
' 交换元素
tmp = arr(m, 1)
arr(m, 1) = arr(n, 1)
arr(n, 1) = tmp
Next m
For i = 2 To lastRow    '对列号循环
ws.Cells(j, i).Value = arr(i - 1, 1)
Next
Next
Set rng2 = Range(ws.Cells(1, 1), ws.Cells(j - 1, i - 1))
'对单元格进行居中设置
ws.Cells(1, 1).CurrentRegion().HorizontalAlignment = xlCenter
ws.Cells(1, 1).VerticalAlignment = xlCenter
'对田间种植区域添加边框
With rng2.Borders
.LineStyle = xlContinuous
.Weight = xlThin
.Color = RGB(0, 0, 0) ' 黑色
End With
Case "纵向"
'输入列标题
For i = 1 To qz_num
ws.Cells(1, i).Value = "区组" & i
Next
'将品种名称放入对应行排号的单元格中
For j = 1 To qz_num    '对列号循环
' 随机排列数组中的元素
arr = rngValues
Randomize ' 初始化随机数生成器
For m = LBound(arr) To UBound(arr) - 1
n = Int((UBound(arr) - m + 1) * Rnd + m)
' 交换元素
tmp = arr(m, 1)
arr(m, 1) = arr(n, 1)
arr(n, 1) = tmp
Next m
For i = 2 To lastRow    '对行号循环
ws.Cells(i, j).Value = arr(i - 1, 1)
Next
Next
Set rng2 = Range(ws.Cells(1, 1), ws.Cells(i - 1, j - 1))
'对单元格进行居中设置
ws.Cells(1, 1).CurrentRegion().HorizontalAlignment = xlCenter
ws.Cells(1, 1).VerticalAlignment = xlCenter
'对田间种植区域添加边框
With rng2.Borders
.LineStyle = xlContinuous
.Weight = xlThin
.Color = RGB(0, 0, 0) ' 黑色
End With
Case Else
MsgBox "无此排列类型,请重新选择"
End Select
Else    '有排区号的情况
Select Case pl
Case "横向"
'输入行标题
For i = 1 To qz_num * 2 Step 2
ws.Cells(i, 1).Value = "排区号"
Next
For i = 2 To qz_num * 2 Step 2
ws.Cells(i, 1).Value = "品种名称"
Next
'将品种名称放入对应行排号的单元格中
For j = 1 To qz_num * 2  '对行号循环
If j Mod 2 = 1 Then    '对行号进行判断,若为奇数则输入排区号
For i = 2 To lastRow    '对列号循环
ws.Cells(j, i).Value = "'" & (Int(j / 2) + 1) & "-" & (i - 1)
Next
Else    '对行号进行判断,若为偶数则输入品种名称
' 随机排列数组中的元素
arr = rngValues
Randomize ' 初始化随机数生成器
For m = LBound(arr) To UBound(arr) - 1
n = Int((UBound(arr) - m + 1) * Rnd + m)
' 交换元素
tmp = arr(m, 1)
arr(m, 1) = arr(n, 1)
arr(n, 1) = tmp
Next m
For i = 2 To lastRow    '对列号循环
ws.Cells(j, i).Value = arr(i - 1, 1)
Next
End If
Next
Set rng2 = Range(ws.Cells(1, 1), ws.Cells(j - 1, i - 1))
'对单元格进行居中设置
ws.Cells(1, 1).CurrentRegion().HorizontalAlignment = xlCenter
ws.Cells(1, 1).VerticalAlignment = xlCenter
'对田间种植区域添加边框
With rng2.Borders
.LineStyle = xlContinuous
.Weight = xlThin
.Color = RGB(0, 0, 0) ' 黑色
End With
Case "纵向"
'输入列标题
For i = 1 To qz_num * 2 Step 2
ws.Cells(1, i).Value = "排区号"
Next
For i = 2 To qz_num * 2 Step 2
ws.Cells(1, i).Value = "品种名称"
Next
'将品种名称放入对应行排号的单元格中
For j = 1 To qz_num * 2  '对列号循环
If j Mod 2 = 1 Then    '对列号进行判断,若为奇数则输入排区号
For i = 2 To lastRow    '对列号循环
ws.Cells(i, j).Value = "'" & (Int(j / 2) + 1) & "-" & (i - 1)
Next
Else    '对列号进行判断,若为偶数则输入品种名称
' 随机排列数组中的元素
arr = rngValues
Randomize ' 初始化随机数生成器
For m = LBound(arr) To UBound(arr) - 1
n = Int((UBound(arr) - m + 1) * Rnd + m)
' 交换元素
tmp = arr(m, 1)
arr(m, 1) = arr(n, 1)
arr(n, 1) = tmp
Next m
For i = 2 To lastRow    '对列号循环
ws.Cells(i, j).Value = arr(i - 1, 1)
Next
End If
Next
Set rng2 = Range(ws.Cells(1, 1), ws.Cells(i - 1, j - 1))
'对单元格进行居中设置
ws.Cells(1, 1).CurrentRegion().HorizontalAlignment = xlCenter
ws.Cells(1, 1).VerticalAlignment = xlCenter
'对田间种植区域添加边框
With rng2.Borders
.LineStyle = xlContinuous
.Weight = xlThin
.Color = RGB(0, 0, 0) ' 黑色
End With
Case Else
MsgBox "无此排列类型,请重新选择"
End Select
End If
Application.ScreenUpdating = True       '刷新屏幕开启
Application.DisplayAlerts = True        '警告提示框开启
End Sub

本站无任何商业行为
个人在线分享 » 一个可以自动生成随机区组试验的excel VBA小程序
E-->