窗体FrmEqualityPrep.frm Option Explicit Option Base 1 Private Sub

advertisement
窗体 FrmEqualityPrep.frm
Option Explicit
Option Base 1
Private Sub Form_Load()
optDataShare.Value = True
cbxMethod.ListIndex = 1
lstSData.Clear
End Sub
Private Sub optDataInput_Click()
optDataInput.Value = True
Frame3.Enabled = True
txtIndex.Enabled = False
End Sub
Private Sub optDataShare_Click()
optDataShare.Value = True
Frame3.Enabled = False
txtIndex.Enabled = True
End Sub
Private Sub cbExit_Click()
Unload Me
End Sub
' Event Procedures for input source data: Means and GroupNames
Private Sub cbAdd_Click()
Dim pLine As String
Dim I As Integer, St As String
If Len(txtMean.Text) = 0 Then
MsgBox "请先填好方差值!", vbExclamation
Exit Sub
End If
If Not IsNumeric(txtMean.Text) Then
MsgBox "方差值必须为数字!", vbExclamation
Exit Sub
End If
pLine = Format(txtMean.Text, "0000.000
") & _
Format(txtGName.Text, "!@@@@@@@@@@")
'
' Format is based on Charactor not on Byte! So, when mixed with ASCII and _
DBCS chars in Chinese Version, String with same lenth may have different _
width on Screen !!!
I = IIf(lstSData.ListCount = 0, 0, lstSData.ListCount)
lstSData.AddItem pLine, I
lstSData.ListIndex = I
txtMean.SetFocus
End Sub
Private Sub cbDelete_Click()
Dim I As Integer
If lstSData.ListIndex = -1 Then
MsgBox "请先选好要删除的行!", vbExclamation
Exit Sub
End If
I = lstSData.ListIndex
lstSData.RemoveItem I
If lstSData.ListCount > 0 Then lstSData.ListIndex = IIf(I = 0, 0, I - 1)
End Sub
Private Sub cbDown_Click()
Dim sTemp As String
Dim I As Integer
I = lstSData.ListIndex
If I = lstSData.ListCount - 1 Then
Beep
Exit Sub
End If
sTemp = lstSData.List(I)
lstSData.RemoveItem I
I=I+1
lstSData.AddItem sTemp, I
lstSData.ListIndex = I
End Sub
Private Sub cbUP_Click()
Dim sTemp As String
Dim I As Integer
I = lstSData.ListIndex
If I = 0 Then
Beep
Exit Sub
End If
sTemp = lstSData.List(I)
lstSData.RemoveItem I
I=I-1
lstSData.AddItem sTemp, I
lstSData.ListIndex = I
End Sub
Private Sub cbRun_Click()
Dim sVariance() As Double
Dim idFx As Integer, n As Integer
Dim iMethod As Integer
Dim iReturn As Integer, I As Integer, strT As String
I = cbxMethod.ListIndex
iMethod = cbxMethod.ItemData(I)
If optDataShare.Value Then
' use Sample data for Anova analysis
If Not IsNumeric(txtIndex.Text) Then
MsgBox "请输入试点序号!
(0 代表多点联合分析)", vbOKOnly + vbExclamation
txtIndex.SetFocus
Exit Sub
End If
iReturn = objAnova.EqualityAnova(Val(txtIndex.Text), iMethod)
Else
' all data should be provided here
' Check parameters
If Not IsNumeric(txtdFx.Text) Then
MsgBox "请输入自由度值,它必须为数字!", vbExclamation
Exit Sub
Else
idFx = Val(txtdFx.Text)
End If
If lstSData.ListCount < 2 Then
MsgBox "至少要有两组方差值数据才能进同质性检验!", vbExclamation
Exit Sub
Else
n = lstSData.ListCount
ReDim sVariance(n), VarIDs(n)
For I = 0 To n - 1
strT = lstSData.List(I)
sVariance(I + 1) = Val(Left(strT, 10))
VarIDs(I + 1) = Trim(Mid(strT, 11))
Next
End If
iReturn = objAnova.EqualityWSD(sVariance, idFx, iMethod)
End If
If iReturn <> caiOK Then
TestAnovaMain.txtMessage.Text = TestAnovaMain.txtMessage.Text & vbCrLf & Time() &
_
"
同质性检验失败!" & vbCrLf & objAnova.strMessage
TestAnovaMain.Show
Exit Sub
End If
EqualityPresent
TestAnovaMain.Show
End Sub
Public Sub EqualityPresent()
Dim strT As String, strS As String
Dim ctEquRpt As AnovaCom.EqualityResult
ctEquRpt = objAnova.ctEqTestResult
With ctEquRpt
strT = vbCrLf & Time() & "
参试组样本方差间的同质性检验顺利完成。" & vbCrLf
strT = strT & "方法名称:" & Format(.MethodName, "!@@@@@@@@@@@") &
vbCrLf
strT = strT & "参试组个数:" & Format(.Size, "000;") & " 各方差的自由度:" &
Format(.dF, "000") & vbCrLf
strS = IIf(.MethodName = "Cochran", "G_Max", "X_Square")
strT = strT & "计算得同质性评估指数 " & strS & " = " & Format(.EvalValue, "##0.000")
& vbCrLf
strT = strT & "对应的临界值:α=0.05 时为" & Format(.CritVal005, "##0.000;") & "
α=0.01 时为" & Format(.CritVal001, "##0.000;") & vbCrLf
Select Case .Result
Case 0
strS = "各参试组的样本方差间的同质性可以接受。"
Case 1
strS = "各参试组的样本方差间的差异显著。
(错判概率小于 5%)"
Case 2
strS = "各参试组的样本方差间的差异极显著。(错判概率小于 1%)"
End Select
strT = strT & "检验结论:" & strS & vbCrLf
End With
TestAnovaMain.txtMessage.Text = TestAnovaMain.txtMessage.Text & strT
End Sub
窗体 frmGetSDataExcel.frm
Option Explicit
Option Base 1
Private exlApp As Excel.Application, exlWBook As Excel.Workbook
Private exlRg As Excel.Range
Private Const cState0 As String = "初始状态:没连结任何 Excel 工作簿文件。"
Private Const cState1 As String = "连接工作簿成功;等待导入样本数据。"
Private Const cState2 As String = "开始导入样本数据,请稍侯。"
'Private Const cState3 As String = "开始导入生产试验数据,请稍侯。"
Private Const cState4 As String = "当前工作簿中的样本数据已成功地读入。"
Private Const cStateErr As String = "操作失败!"
Private Sub Form_Load()
txtState = cState0
txtPathName = ""
cbActions(1).Enabled = False
ProgressBar1.Value = 0
cdlDialog1.Filter = "Excel Workbook (*.xls)|*.xls"
Me.Height = 5790
Me.Width = 7950
End Sub
Private Sub Form_Unload(Cancel As Integer)
If Not exlWBook Is Nothing Then
exlWBook.Close
Set exlWBook = Nothing
End If
If Not exlApp Is Nothing Then
exlApp.Quit
Set exlApp = Nothing
End If
End Sub
Private Sub cbBrows_Click()
' Get file name from the Common Dialog Box, i.e. cdlDialog1
On Error Resume Next
cdlDialog1.CancelError = True
cdlDialog1.ShowOpen
If Err.Number = cdlCancel Then
lbInit:
txtPathName = ""
txtState.Text = cState0
ProgressBar1.Value = 0
Exit Sub
' Cancel button is pressed
End If
txtPathName.Text = cdlDialog1.FileName
If Len(txtState.Text) < 5 Then
MsgBox "你尚未选择有效的工作簿路径名!", vbOKOnly + vbExclamation
GoTo lbInit
Else
ProgressBar1.Value = 2
txtState.Text = cState0
End If
End Sub
Private Sub cbActions_Click(Index As Integer)
Dim iReturn As Integer
Dim bVisible As Boolean
Select Case Index
Case 0
If Len(txtPathName.Text) < 5 Or Right(txtPathName.Text, 3) <> "xls" Then
MsgBox "请先确定 Excel 工作簿的路径名!", vbOKOnly + vbExclamation
Exit Sub
End If
bVisible = chkVisible.Value
iReturn = AccessExcelWBook(txtPathName.Text, bVisible)
If iReturn = caiOK Then
txtState = cState1
cbActions(1).Enabled = True
ProgressBar1.Value = 30
Else
txtState = cStateErr & strMessage & vbCrLf _
& "请检查后重新连结。"
cbActions(1).Enabled = False
ProgressBar1.Value = 0
iDState = 0
End If
Case 1
txtState = cState2
iReturn = GetSampleDataExcel()
If iReturn = caiOK Then
txtState = cState4
TestAnovaMain!txtMessage.Text = Time() & "
样本数据收集完毕。 " & vbCrLf
Else
txtState = cStateErr & strMessage
ProgressBar1.Value = 0
End If
Case 2
Unload Me
End Select
End Sub
Function AccessExcelWBook(strPathName As String, bVisible As Boolean) As Integer
On Error GoTo errAccessExcel
Set exlApp = CreateObject("Excel.Application")
If bVisible Then
exlApp.WindowState = xlMaximized
exlApp.Visible = True
Else
exlApp.Visible = False
End If
Set exlWBook = exlApp.Workbooks.Open(strPathName, 0)
' "0",the 2nd. Para., means no link to be updated when open the workbook
Set exlRg = exlWBook.Worksheets.Item(1).Range("PlotYields")
AccessExcelWBook = caiOK
Exit Function
errAccessExcel:
If Err.Number = 9 Then
strMessage = "该工作簿中没按规定设立小区产量数据区域!无法获得数据。" _
& vbCrLf & "它应在第一张工作表上且定义为“PlotYields”
。"
ElseIf Err.Number = 1004 Then
strMessage = "找不到指定的工作簿,路径名不对!建议利用《浏览》键查找。"
Else
strMessage = "操作失败,未能获得小区产量数据!"
End If
AccessExcelWBook = caiError
End Function
Function GetSampleDataExcel() As Integer
Dim n1 As Integer, n2 As Integer, n3 As Integer
Dim vT As Variant, lOffset As Long
Dim I As Integer, J As Integer, K As Integer
Dim strMessage As String
' Set Dimentions of Sample Data and get IDs/Names of Sites and Varieties
On Error GoTo errR
n3 = exlRg.Columns.Count
lOffset = exlRg.Column
J = 3 + 1 - lOffset
vT = exlRg.Cells(1, J).Value
I=2
Do While exlRg.Cells(I, J).Value <> vT
I=I+1
Loop
n2 = I - 1
n1 = Int(exlRg.Rows.Count / n2)
ReDim sData(n1, n2, n3), SiteIDs(n1), VarIDs(n2)
' Reading Variety Names
J=J+1
For I = 1 To n2
VarIDs(I) = exlRg.Cells(I, J).Value
Next
' Reading Site IDs
J=J-2
For I = 1 To n1
SiteIDs(I) = exlRg.Cells(n2 * (I - 1) + 1, J).Value
Next
ProgressBar1.Value = 50
' Reading Plot Yields
For I = 1 To n1
For J = 1 To n2
For K = 1 To n3
sData(I, J, K) = exlRg.Cells(n2 * (I - 1) + J, K).Value
If exlRg.Cells(n2 * (I - 1) + J, 4).Value <> 0.02 Then
vT = exlRg.Cells(n2 * (I - 1) + J, 4).Value
vT = 0.02 / vT
sData(I, J, K) = sData(I, J, K) * vT
End If
Next K
Next J
Next I
ProgressBar1.Value = 100
iDState = 1
GetSampleDataExcel = caiOK
Exit Function
errR:
iDState = 0
ReDim sData(1), SiteIDs(1), VarIDs(1)
strMessage = "读入样本数据时出错!" _
& " 错误代码:" & CStr(Err.Number) & vbCrLf _
& "说明:" & Err.Description
GetSampleDataExcel = caiError
End Function
窗体 frmMCompPrep.frm
Option Explicit
Option Base 1
Private Sub Form_Load()
optDataShare.Value = True
cbxMethod.ListIndex = 1
cbxMode.ListIndex = 1
lstSData.Clear
End Sub
Private Sub optDataInput_Click()
optDataInput.Value = True
Frame3.Enabled = True
End Sub
Private Sub optDataShare_Click()
optDataShare.Value = True
Frame3.Enabled = False
End Sub
Private Sub cbExit_Click()
Unload Me
End Sub
' Event Procedures for input source data: Means and GroupNames
Private Sub cbAdd_Click()
Dim pLine As String
Dim I As Integer, St As String
If Len(txtMean.Text) = 0 Or Len(txtGName.Text) = 0 Then
MsgBox "请先填好平均值和名称两项!", vbExclamation
Exit Sub
End If
If Not IsNumeric(txtMean.Text) Then
MsgBox "平均值必须为数字!", vbExclamation
Exit Sub
End If
'
pLine = Format(txtMean.Text, "0000.000
") & _
Format(txtGName.Text, "!@@@@@@@@@@")
' Format is based on Charactor not on Byte! So, when mixed with ASCII and _
DBCS chars in Chinese Version, String with same lenth may have different _
width on Screen !!!
I = IIf(lstSData.ListCount = 0, 0, lstSData.ListCount)
lstSData.AddItem pLine, I
lstSData.ListIndex = I
End Sub
Private Sub cbDelete_Click()
Dim I As Integer
If lstSData.ListIndex = -1 Then
MsgBox "请先选好要删除的行!", vbExclamation
Exit Sub
End If
I = lstSData.ListIndex
lstSData.RemoveItem I
If lstSData.ListCount > 0 Then lstSData.ListIndex = IIf(I = 0, 0, I - 1)
End Sub
Private Sub cbDown_Click()
Dim sTemp As String
Dim I As Integer
I = lstSData.ListIndex
If I = lstSData.ListCount - 1 Then
Beep
Exit Sub
End If
sTemp = lstSData.List(I)
lstSData.RemoveItem I
I=I+1
lstSData.AddItem sTemp, I
lstSData.ListIndex = I
End Sub
Private Sub cbUP_Click()
Dim sTemp As String
Dim I As Integer
I = lstSData.ListIndex
If I = 0 Then
Beep
Exit Sub
End If
sTemp = lstSData.List(I)
lstSData.RemoveItem I
I=I-1
lstSData.AddItem sTemp, I
lstSData.ListIndex = I
End Sub
Private Sub cbRun_Click()
Dim sMeans() As Double
Dim dMSx As Double, idFx As Integer, n As Integer
Dim iMode As Integer, iMethod As Integer
Dim iReturn As Integer, I As Integer, strT As String
I = cbxMode.ListIndex
iMode = cbxMode.ItemData(I)
I = cbxMethod.ListIndex
iMethod = cbxMethod.ItemData(I)
If optDataShare.Value Then
' use Sample data for Anova analysis
iReturn = objAnova.MultiCompareAnova(iMethod, iMode)
Else
' all data should be provided here
' Check parameters
If Not IsNumeric(txtMSx.Text) Then
MsgBox "请输入均方差值,它必须为数字!", vbExclamation
Exit Sub
Else
dMSx = Val(txtMSx.Text)
End If
If Not IsNumeric(txtdFx.Text) Then
MsgBox "请输入自由度值,它必须为数字!", vbExclamation
Exit Sub
Else
idFx = Val(txtdFx.Text)
End If
If Not IsNumeric(txtN.Text) Then
MsgBox "请输入样本容量值,它必须为数字!", vbExclamation
Exit Sub
Else
n = Val(txtN.Text)
End If
If lstSData.ListCount < 2 Then
MsgBox "至少要有两组平均值数据才能进行多重比较!", vbExclamation
Exit Sub
Else
iMode = lstSData.ListCount
ReDim sMeans(iMode), VarIDs(iMode)
For I = 0 To iMode - 1
strT = lstSData.List(I)
sMeans(I + 1) = Val(Left(strT, 10))
VarIDs(I + 1) = Trim(Mid(strT, 11))
Next
End If
iReturn = objAnova.MultiCompareWSD(sMeans, dMSx, idFx, n, iMethod)
End If
If iReturn <> caiOK Then
TestAnovaMain.txtMessage.Text = TestAnovaMain.txtMessage.Text & vbCrLf & Time() &
_
"
多重比较失败!" & vbCrLf & objAnova.strMessage
TestAnovaMain.Show
Exit Sub
End If
MultiCompPresent
TestAnovaMain.Show
End Sub
Public Sub MultiCompPresent()
Dim strT As String
Dim ctMCRpt As AnovaCom.MCReport
Dim I As Integer, n As Integer
n = UBound(VarIDs)
strT = vbCrLf & Time() & "
完成多重比较,各品种名,平均产量,及其级别如下列:"
& vbCrLf
For I = 1 To n
ctMCRpt = objAnova.ctMCompReport(I)
With ctMCRpt
strT = strT & " ▲ " & Format(.Mean, "000.00") & ", " & .Classif _
& Format(VarIDs(.Index), " !@@@@@@@@") & vbCrLf
End With
Next
TestAnovaMain.txtMessage.Text = TestAnovaMain.txtMessage.Text & strT
End Sub
窗体 frmRegressionPrep.frm
Option Explicit
Option Base 1
Private Sub Form_Load()
optDataShare.Value = True
lstSData.Clear
End Sub
Private Sub optDataInput_Click()
optDataInput.Value = True
Frame3.Enabled = True
Frame2.Enabled = False
End Sub
Private Sub optDataShare_Click()
optDataShare.Value = True
Frame3.Enabled = False
Frame2.Enabled = True
End Sub
Private Sub cbExit_Click()
Unload Me
End Sub
' Event Procedures for input source data: Means and GroupNames
Private Sub cbAdd_Click()
Dim pLine As String
Dim I As Integer, St As String
If Len(txtX.Text) = 0 Or Len(txtY.Text) = 0 Then
MsgBox "请先填好样本 X 和 Y 的值!", vbExclamation
Exit Sub
End If
If Not (IsNumeric(txtX.Text) And IsNumeric(txtY.Text)) Then
MsgBox "X、Y 的样本值必须为数字!", vbExclamation
Exit Sub
End If
pLine = Format(txtX.Text, "0000.000
") & _
Format(txtY.Text, "0000.000")
'
' Format is based on Charactor not on Byte! So, when mixed with ASCII and _
DBCS chars in Chinese Version, String with same lenth may have different _
width on Screen !!!
I = IIf(lstSData.ListCount = 0, 0, lstSData.ListCount)
lstSData.AddItem pLine, I
lstSData.ListIndex = I
txtX.SetFocus
End Sub
Private Sub cbDelete_Click()
Dim I As Integer
If lstSData.ListIndex = -1 Then
MsgBox "请先选好要删除的行!", vbExclamation
Exit Sub
End If
I = lstSData.ListIndex
lstSData.RemoveItem I
If lstSData.ListCount > 0 Then lstSData.ListIndex = IIf(I = 0, 0, I - 1)
End Sub
Private Sub cbDown_Click()
Dim sTemp As String
Dim I As Integer
I = lstSData.ListIndex
If I = lstSData.ListCount - 1 Then
Beep
Exit Sub
End If
sTemp = lstSData.List(I)
lstSData.RemoveItem I
I=I+1
lstSData.AddItem sTemp, I
lstSData.ListIndex = I
End Sub
Private Sub cbUP_Click()
Dim sTemp As String
Dim I As Integer
I = lstSData.ListIndex
If I = 0 Then
Beep
Exit Sub
End If
sTemp = lstSData.List(I)
lstSData.RemoveItem I
I=I-1
lstSData.AddItem sTemp, I
lstSData.ListIndex = I
End Sub
Private Sub cbRun_Click()
Dim sXs() As Double, sYs() As Double
Dim n As Integer
Dim iReturn As Integer, I As Integer, strT As String
If optDataShare.Value Then
' use Sample data for Anova analysis
If Not IsNumeric(txtIndex.Text) Then
MsgBox "请输入所选的因子 B(品种)的序号!", vbOKOnly + vbExclamation
txtIndex.SetFocus
Exit Sub
End If
iReturn = objAnova.RegressionAnova(Val(txtIndex.Text))
Else
' all data should be provided here
If lstSData.ListCount < 4 Then
MsgBox "至少要有 4 组样本数据才能进回归分析!", vbExclamation
Exit Sub
Else
n = lstSData.ListCount
ReDim sXs(n), sYs(n)
For I = 0 To n - 1
strT = lstSData.List(I)
sXs(I + 1) = Val(Left(strT, 10))
sYs(I + 1) = Val(Trim(Mid(strT, 11)))
Next
End If
iReturn = objAnova.RegressionWSD(sXs(), sYs(), n)
End If
If iReturn <> caiOK Then
TestAnovaMain.txtMessage.Text = TestAnovaMain.txtMessage.Text & vbCrLf & Time() &
_
"
回归分析失败!" & vbCrLf & objAnova.strMessage
TestAnovaMain.Show
Exit Sub
End If
RegressionPresent
TestAnovaMain.Show
End Sub
Public Sub RegressionPresent()
Dim strT As String, strS As String
Dim ctRegRpt As AnovaCom.RegresionResult
ctRegRpt = objAnova.ctRegresResult
With ctRegRpt
strT = vbCrLf & Time() & "
回归分析及相关性检验顺利完成。" & vbCrLf
strT = strT & "样本个数:" & Format(.Size, "000;") & vbCrLf
strT = strT & "计算得回归方程‘Y = kX + b’ 的系数: k =" & Format(.Slope, "#0.0000;
") _
& " b =" & Format(.Intercept, "#0.0000;") & vbCrLf
strT = strT & "X 和 Y 之间的样本相关系数:" & Format(.CorCorf, "0.00000") & vbCrLf
strT = strT & "判断相关性的临界值:α=0.05 时为" & Format(.CritRa005, "0.00000;
") _
& " α=0.01 时为" & Format(.CritRa001, "0.00000;") & vbCrLf
Select Case .Result
Case 0
strS = "随机变量 X 和 Y 相互之间的独立性可以接受。"
Case 1
strS = "随机变量 X 和 Y 相互之间是相关的。
(错判概率小于 5%)"
Case 2
strS = "随机变量 X 和 Y 相互之间是相关的。
(错判概率小于 1%)"
End Select
strT = strT & "检验结论:" & strS & vbCrLf
End With
TestAnovaMain.txtMessage.Text = TestAnovaMain.txtMessage.Text & strT
End Sub
窗体 TestAnovaMain.frm
Option Explicit
Option Base 1
Private Sub Form_Load()
Set objAnova = New clsStatisAnova
Me.Height = 5790
Me.Width = 7950
txtMessage.Text = Time() & "
主页启动 " & vbCrLf
End Sub
Private Sub Form_Unload(Cancel As Integer)
Set objAnova = Nothing
End Sub
Private Sub cbExit_Click()
Unload Me
End Sub
Private Sub cbClean_Click()
txtMessage.Text = Time() & "
End Sub
擦清公告牌,删除所有历史记录。 " & vbCrLf
Private Sub cbGetSData_Click()
frmGetSDataExcel.Show
End Sub
Private Sub cbSendSData_Click()
Dim iReturn As Integer
iReturn = objAnova.SetSampleData(sData, 3)
If iReturn = caiOK Then
txtMessage.Text = txtMessage.Text & Time() & _
"
样本数据已成功地传输给统计分析部件:objAnova 。 " & vbCrLf
Else
txtMessage.Text = txtMessage.Text & Time() & _
"
样本数据传输失败! " & vbCrLf & objAnova.strMessage & vbCrLf
End If
End Sub
Private Sub cbAnova2WOD_Click()
Dim iReturn As Integer
iReturn = objAnova.Anova2WOD(cRadomized)
If iReturn <> caiOK Then
txtMessage.Text = txtMessage.Text & vbCrLf & Time() & _
"
联合方差分析失败!" & vbCrLf & objAnova.strMessage
Exit Sub
End If
If objAnova.iAnovaResultState = 22 Then
Anova2Present "联合"
End If
End Sub
Private Sub cbAnova2WSD_Click()
Dim iReturn As Integer
iReturn = objAnova.Anova2Wsd(sData, cRadomized)
If iReturn <> caiOK Then
txtMessage.Text = txtMessage.Text & vbCrLf & Time() & _
"
联合方差分析失败!" & vbCrLf & objAnova.strMessage
Exit Sub
End If
If objAnova.iAnovaResultState = 22 Then
Anova2Present "联合"
End If
End Sub
Private Sub cbAnova2gWOD_Click()
Dim iReturn As Integer
iReturn = objAnova.Anova2gWOD(4)
If iReturn <> caiOK Then
txtMessage.Text = txtMessage.Text & vbCrLf & Time() & _
"
双因子随机区组试验方差分析失败!" & vbCrLf & objAnova.strMessage
Exit Sub
End If
If objAnova.iAnovaResultState = 22 Then
Anova2Present "双因子随机区组试验"
End If
End Sub
Private Sub cbAnova1WOD_Click()
Dim iReturn As Integer, strT As String
Dim Idx As Integer
Idx = 0
Do Until Idx > 0
strT = InputBox("请输入所选试点的序号:")
If IsNumeric(strT) Then
Idx = Val(strT)
Else
MsgBox "试点序号必须是正整数!", vbOKOnly + vbExclamation
End If
Loop
iReturn = objAnova.Anova1WOD(Idx)
If iReturn <> caiOK Then
txtMessage.Text = txtMessage.Text & vbCrLf & Time() & _
"
单点方差分析失败!" & vbCrLf & objAnova.strMessage
Exit Sub
End If
If objAnova.iAnovaResultState = 12 Then
Anova1Present SiteIDs(Idx)
End If
End Sub
Private Sub cbAnova1WSD_Click()
Dim iReturn As Integer, strT As String
Dim Idx As Integer, I As Integer, J As Integer
Dim Data1() As Single, n2 As Integer, n3 As Integer
Idx = 0
Do Until Idx > 0
strT = InputBox("请输入所选试点的序号:")
If IsNumeric(strT) Then
Idx = Val(strT)
Else
MsgBox "试点序号必须是正整数!", vbOKOnly + vbExclamation
End If
Loop
n2 = UBound(sData, 2)
n3 = UBound(sData, 3)
ReDim Data1(n2, n3)
For I = 1 To n2
For J = 1 To n3
Data1(I, J) = sData(Idx, I, J)
Next J
Next I
iReturn = objAnova.Anova1WSD(Data1)
If iReturn <> caiOK Then
txtMessage.Text = txtMessage.Text & vbCrLf & Time() & _
"
单点方差分析失败!" & vbCrLf & objAnova.strMessage
Exit Sub
End If
If objAnova.iAnovaResultState = 12 Then
Anova1Present SiteIDs(Idx)
End If
End Sub
Private Sub cbMultiCompare_Click()
frmMCompPrep.Show
End Sub
Private Sub cbEquality_Click()
frmEqualityPrep.Show
End Sub
Private Sub cbRegress_Click()
frmRegressionPrep.Show
End Sub
' Present the result of Anova2 Analysis
Sub Anova2Present(strAnova2Type As String)
Dim strT As String
Dim ctAResult As AnovaCom.AnovaStatis
ctAResult = objAnova.ctAnovaResult
strT = vbCrLf & Time() & "
下列:" & vbCrLf
With ctAResult
完成" & strAnova2Type & "方差分析,获得相关的统计量如
strT = strT & " ▲自由度:dFt =" & Format(.dFt, "000") & "; dFsite =" & Format(.dFa,
"000") _
& "; dFv =" & Format(.dFb, "000") & "; dFsv=" & Format(.dFab, "000") & "; dFr ="
& Format(.dFr, "000") _
& "; dFerr =" & Format(.dFerr, "000") & "。" & vbCrLf
strT = strT & " ▲均方差:MSs =" & Format(.SSa / .dFa, "##0.000") & "; MSv =" &
Format(.SSb / .dFb, "##0.000") _
& "; MSab =" & Format(.SSab / .dFab, "##0.000") & "; MSr =" & Format(.SSr / .dFr,
"##0.000") _
& "; MSerr =" & Format(.SSerr / .dFerr, "##0.000") & "。" & vbCrLf _
& " ▲总平方和:SStot =" & Format(.SSt, "##0.000") & "。" & vbCrLf
strT = strT & " ▲F 检验:FVv = " & Format(.FVb, "#0.000") & "; FPv =" & Format(.FPb,
"0.0000") _
& "; FVsv =" & Format(.FVab, "0.000") & "; FPsv =" & Format(.FPab, "0.0000") _
& "; FVs =" & Format(.FVa, "0.000") & "; FPs =" & Format(.FPa, "0.0000") _
& "; FVr =" & Format(.FVr, "0.000") & "; FPr =" & Format(.FPr, "0.0000") & "。" &
vbCrLf
End With
txtMessage.Text = txtMessage.Text & strT
End Sub
' Present the result of Anova1 Analysis
Sub Anova1Present(strSiteID As String)
Dim strT As String
Dim ctAResult As AnovaCom.AnovaStatis
ctAResult = objAnova.ctAnovaResult
strT = vbCrLf & Time() & "
完成单点方差分析,获得相关的统计量如下列:" & vbCrLf
strT = strT & "试点 ID = " & strSiteID & vbCrLf
With ctAResult
strT = strT & " ▲自由度:dFt =" & Format(.dFt, "000") & ";" _
& "; dFv =" & Format(.dFb, "000") & "; dFr =" & Format(.dFr, "000") _
& "; dFerr =" & Format(.dFerr, "000") & "。" & vbCrLf
strT = strT & " ▲均方差:MSv =" & Format(.SSb / .dFb, "##0.00") _
& "; MSr =" & Format(.SSr / .dFr, "##0.00") _
& "; MSerr =" & Format(.SSerr / .dFerr, "##0.000") & "。" & vbCrLf _
& " ▲总平方和:SStot =" & Format(.SSt, "##0.000") & "。" & vbCrLf
strT = strT & " ▲F 检验:FVv = " & Format(.FVb, "#0.000") & "; FPv =" & Format(.FPb,
"0.0000") _
& "; FVr =" & Format(.FVr, "0.000") & "; FPr =" & Format(.FPr, "0.0000") & "。" &
vbCrLf
End With
txtMessage.Text = txtMessage.Text & strT
End Sub
模块 AccessAnovaCom.bas
Option Explicit
Option Base 1
' to store the Data of Source Samples
Public sData() As Single
' an instance of class clsStaisAnova
Public objAnova As clsStatisAnova
' States of sData() and other xIDs()
Public iDState As Integer
' 0 -- invalid, 1 -- Valid Data of Plot Yields for a Combined Anova Analysis
' to store the Name or Code of the Test Sites and Crop Varieties
Public SiteIDs() As String, VarIDs() As String
Public strMessage As String
' Return Values of public methods
Public Const caiOK As Integer = 0
Public Const caiCancel As Integer = -1
Public Const caiError As Integer = -2
' for the method of Multiple Comparision
Public Const cMcLSD As Integer = 1
Public Const cMcSSR As Integer = 2
' for Design Mode about Factor A
Public Const cFixed As Integer = 0
Public Const cRadomized As Integer = 1
模块 Declarations.bas
Option Explicit
Option Base 1
'' Define a Type for store the Statistic Values of Anova Analysis
'Public Type AnovaStatis
' ' 自由度
'
dFt As Integer
'
dFa As Integer
'
dFb As Integer
'
dFr As Integer
'
dFab As Integer
'
dFerr As Integer
' Degrees of Freedom -- Total
' ......
-- Factor A, e.g. the "Test Sites"
' ' 平方和
'
SSt As Double
' Total Square Sum of (Xijk-Average(Xijk))
'
SSa As Double
' Total Squire Sum about the First Factor A, e.g. the "Test Sites"
'
SSb As Double
' ...... , e.g. "Varieties"
'
SSr As Double
' ...... , e.g. "Blocks"
'
SSab As Double
' ...... about "Cross Effections"
'
SSerr As Double
' ...... about "Experimental Error"
'
GrandMean As Double ' Mean Value of all Samples
' ' F 值及对应的概率(显著性)
'
FVr As Double
' F Value from Repitations inside factor A. (来自试点内区组); =
(SSr/dFr)/(SSerr/dFerr)
'
FVb As Double
' F Value from factor B, e.g. Varieties. (来自品种);
'
' =(SSb/dFb)/Deno, here Deno=(SSab/dFab) if
in Radomized mode or =(SSerr/dFerr) if Fixed mode
'
FVa As Double
' F Value from factor A, e.g. Test Sites. ( 来 自 试 点 );
=(SSa/dFa)/(SSerr/dFerr)
'
FVab As Double
' F Value from the iteraction of factor A and B. (来自试点 x 品种);
=(SSab/dFab)/(SSerr/dFerr)
'
FPr As Double
' Corresponding significense ......
'
FPb As Double
'
FPa As Double
'
FPab As Double
'End Type
'
'' to store the Result of Multiple Comparision for each Group that presents in MC analysis
'' i.e. the whole result should be stored in an Array of this type and the groups should ordered
descendly
'Public Type MCReport
'
Index As Integer
' Index of the group in the original resource array
'
Mean As Double
' mean value of the group
'
Classif As String
'
' the classifications of the group. its size always=20, with the 1st 10 chars contain _
'
the classification for 0.05 Significance, the last 10, 0.01 Significance, e.g. "
cde
DE
"
'End Type
Public modMessage As String
' Return Values of public methods
Public Const caiOK As Integer = 0
Public Const caiCancel As Integer = -1
Public Const caiError As Integer = -2
Public Const caiNo As Integer = 1
' for the method of Multiple Comparision
Public Const cMcLSD As Integer = 1
Public Const cMcSSR As Integer = 2
' for Design Mode about Factor A
Public Const cFixed As Integer = 0
Public Const cRadomized As Integer = 1
' for method of Equality Test
Public Const cDefault As Integer = 0
Public Const cEqCoch As Integer = 1
Public Const cEqBart As Integer = 2
Public Const cMaxInteger As Integer = &H7FFF
Public Const cNonSense As Single = -9999
模块 StatisFormulas.bas
Option Explicit
Option Base 1
' F Test: n1, n2 --- the 1st and 2nd Degree of Freedom, Fv -- the F Value
'
Return the Significance corresponding to Fv
Function Ftest(dF1 As Integer, dF2 As Integer, Fv As Double) As Double
Dim temp As Double
temp = FDistributing(dF1, dF2, Fv, 1)
temp = 1 - temp
If temp < 0 Then temp = 0
Ftest = temp
End Function
' F Distribution
Function FDistributing(n1 As Integer, n2 As Integer, f As Double, lable_g As Integer) As Double
Dim X As Double, u As Double, p As Double, LU As Double
Dim I As Integer, iAi As Integer, iBi As Integer, nN1 As Integer, nN2 As Integer
If f = 0 Then
FDistributing = 0
Exit Function
End If
X = n1 * f / (n2 + n1 * f)
If Int(n1 / 2) = n1 / 2 Then
If Int(n2 / 2) = n2 / 2 Then
u = X * (1 - X)
p=X
iAi = 2
iBi = 2
Else
u = X * Sqr(1 - X) / 2
p = 1 - Sqr(1 - X)
iAi = 2
iBi = 1
End If
Else
If Int(n2 * 0.5) = n2 * 0.5 Then
p = Sqr(X)
u = p * (1 - X) / 2
iAi = 1
iBi = 2
Else
u = Sqr(X * (1 - X)) / 3.1415926
p = 1 - 2 * Atn(Sqr((1 - X) / X)) / 3.1415926
iAi = 1
iBi = 1
End If
End If
nN1 = n1 - 2
nN2 = n2 - 2
If u = 0 Then
FDistributing = IIf(lable_g, p, 0)
Exit Function
End If
LU = Log(u)
If iAi <> n1 Then
For I = iAi To nN1 Step 2
p=p-2*u/I
LU = LU + Log((1 + iBi / I) * X)
u = Exp(LU)
Next I
End If
If iBi <> n2 Then
For I = iBi To nN2 Step 2
p=p+2*u/I
LU = LU + Log((1 + n1 / I) * (1 - X))
u = Exp(LU)
Next I
End If
FDistributing = IIf(lable_g, p, u / f)
End Function
' To sort source array, i.e. "SrcArr()", an array of any type, and puts the indices of
'
sorted SrcArr() into "SortedIdx()", while keeping "SrcArr()" unchanged,
'
i.e. after successfully return, SrcArr(SortedIdx(i)) should be in sortrd order based on "i".
'
iSize:
the number of elements of both array: SrcArr() and SortedIdx().
' bAsc: indicats the sort order. True -- Ascending; false -- Decsending
' Both Arrays should be allocated with the Base 1 Low Bound by the caller !
Sub SortArray(SrcArr() As Double, iSize As Integer, ByRef SortedIdx() As Integer, bAsc As Boolean)
Dim I As Integer, iStart As Integer
Dim IdxS As Integer, idxO As Integer
Dim vT As Variant
For I = 1 To iSize
SortedIdx(I) = I
Next I
iStart = 1
While iStart < iSize
IdxS = SortedIdx(iStart)
' Sorting, i.e. let SrcArr(idxS) always being the minmum one in a sorting pass
idxO = iStart
' Ordering, i. e. let idxO always satisfies "SortedIdx(idxO) = idxS".
For I = iStart + 1 To iSize
If SrcArr(SortedIdx(I)) < SrcArr(IdxS) Then
IdxS = SortedIdx(I)
idxO = I
End If
Next
SortedIdx(idxO) = SortedIdx(iStart)
SortedIdx(iStart) = IdxS
iStart = iStart + 1
' Now, SrcArr(SortedIdx(1)), SrcArr(SortedIdx(2)),, ..., SrcArr(SortedIdx(iStart))
the ascending order.
Wend
' Now, Sorting Ascendingly is completed
are in
idxO = iSize: I = 1
If bAsc = False Then
While I < idxO
vT = SortedIdx(I)
SortedIdx(I) = SortedIdx(idxO)
SortedIdx(idxO) = vT
I=I+1
idxO = idxO - 1
Wend
' At this point, SrcArr(SortedIdx(i)) will be ordered Decendingly based on i=1, 2, 3, ...
End If
End Sub
' Performs the Multiple Comparesion and put the Comparision Result into cReport() in the format
of "a, ab, b, bcd, ...".
' Mean() contains descendly sorted mean values of groups to be compared; iSize -- number of
groups, iSize must <=20 !
' cReport(): the allocated array of chars of size iSize*20, each of its member have been
initialized to Char " ", Asc(20).
' in fact, the ith group 's result will be put into section of cReport(i*20+1)~cReport(i*20+19),
the first 9 Chars is for 0.05
' significance, and the last 9 are for 0.01 Sibnificance!
' IdxS: cReport(IdxS) will be the first place to put comparision report into
' McType=cMCLSD (=1) -- use LSD method; cMCSSR (=2) -- SSR Duncan method;
' dDev contains a constants, "LSDα" forLSD method; "Deviation" for SSR Duncan
' for SSR Duncan method, SSR will be a Array of Double with size of iSize and contains the SSR
vlaues
Function MultiCompReport(Mean() As Double, iSize As Integer, ByRef cReport() As Integer, IdxS
As Integer, _
dDev As Double, McType As Integer, Optional SSr) As Integer
Dim iB As Integer, iE As Integer, iT As Integer, I As Integer
Dim Cat(9) As Integer
On Error GoTo MCReportFail
iE = 2: iB = 1: iT = 1
Cat(1) = 0
While (iE < iSize + 1)
Select Case McType
Case cMcLSD
' LSD method
Do While Mean(iB) - Mean(iE) <= dDev
iE = iE + 1
If iE = iSize + 1 Then Exit Do
Loop
Case cMcSSR
' SSR Duncan
Do While Mean(iB) - Mean(iE) <= dDev * SSr(iE - iB)
iE = iE + 1
If iE = iSize + 1 Then Exit Do
Loop
Case Else
modMessage = "当前仅支持 LSD 和 SSR-Duncan 两种多重比较法,请选择
其中只一。"
MultiCompReport = caiCancel
Exit Function
End Select
If iE > Cat(iT) Then
For I = iB To iE - 1
cReport(IdxS + (I - 1) * 20 + iT) = Asc("a") + iT - 1
Next
iT = iT + 1
Cat(iT) = iE
End If
iB = iB + 1
If iB = iE Then
iE = iE + 1
If iE = iSize + 1 Then
cReport(IdxS + (iB - 1) * 20 + iT) = Asc("a") + iT - 1
End If
End If
Wend
MultiCompReport = caiOK
Exit Function
MCReportFail:
modMessage = "生成多重比较报告时出错!错误号:" & Err.Number & vbCrLf _
& "说明:" & Err.Description
MultiCompReport = caiError
End Function
模块 StatisTables.bas
Option Explicit
Option Base 1
'
*******************************************************************************
' 本模块提供对一些常用的数理统计表的查询服务。除特别说明外,数据来自:
'
《常用数理统计表》
,中科院数学所概率统计室,科学出版社,1979
'
*******************************************************************************
' 根据给定的自由度及α值(仅限于 0.05 及 0.01,否则返回负数)返回对应的 Tα值
' 数据来自 P.8:7. t 分布的双侧分位数表
Function TTest(idF As Integer, dAlpha As Single) As Double
Dim tValues() As Variant
On Error GoTo TTestFail
Select Case dAlpha
Case 0.05
tValues() = Array(12.706, 4.303, 3.182, 2.776, 2.571, 2.447, 2.365, 2.306, 2.262,
2.228, 2.201, 2.179, 2.16, 2.145, 2.131, 2.12, 2.11, _
2.101, 2.093, 2.086, 2.08, 2.074, 2.069, 2.064, 2.06, 2.056, 2.052, 2.048, 2.045,
2.042, 2.021, 2#, 1.98, 1.96)
Case 0.01
tValues() = Array(63.657, 9.925, 5.841, 4.604, 4.032, 3.707, 3.499, 3.355, 3.25,
3.169, 3.106, 3.055, 3.012, 2.977, 2.947, 2.921, 2.898, _
2.878, 2.861, 2.845, 2.831, 2.819, 2.807, 2.797, 2.787, 2.779, 2.771, 2.763,
2.756, 2.75, 2.704, 2.66, 2.617, 2.576)
Case Else
modMessage = "本部件当前仅支持 0.05 及 0.01 两种显著性!"
TTest = caiCancel
Exit Function
End Select
Select Case idF
Case Is <= 30
TTest = tValues(idF)
Case 31 To 40
TTest = tValues(31)
Case 41 To 50
TTest = tValues(32)
Case 61 To 120
TTest = tValues(33)
Case Is > 120
TTest = tValues(34)
End Select
Exit Function
TTestFail:
modMessage = "检索多重比较 LSD t 分布值时出错!错误号:" & Err.Number & vbCrLf _
& "说明:" & Err.Description
TTest = caiError
End Function
' 按给定的自由度(idF)、处理个数(iSize<=20)及显著水平(iSigLevel= 0.05 or 0.01)提供 SSR 值。
' 当本函数顺利完成时(返回 CaiOK)dSSR()即含有这些 SRR 值。dSSR() 应该含有 iSize-1 个
member
' 数据源:
《农业试验统计》
,莫惠栋,p.592 表 10 ?
Function DuncanSSR(ByRef dSSR() As Double, iSize As Integer, idF As Integer, dSigLevel As Double)
As Integer
Dim I As Integer, iT As Integer
Dim SSr() As Variant, Sz() As Variant
On Error GoTo SSRFail
If iSize > 20 Then
' the <SSRValue Table> avialable to me only supports the multi-Comparision of 20
treatments
DuncanSSR = caiCancel
Exit Function
Else
Sz() = Array(2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 16, 18, 20)
End If
' Assign the SSR Values for given dFs to Array SSR().
Select Case dSigLevel
Case 0.01
Select Case idF
Case 1
SSr() = Array(90#, 90#, 90#, 90#, 90#, 90#, 90#, 90#, 90#, 90#, 90#, 90#,
90#, 90#)
Case 2
SSr() = Array(14#, 14#, 14#, 14#, 14#, 14#, 14#, 14#, 14#, 14#, 14#, 14#,
14#, 14#)
Case 3
SSr() = Array(8.26, 8.5, 8.6, 8.7, 8.8, 8.9, 8.9, 9#, 9#, 9#, 9.1, 9.2, 9.3, 9.3)
Case 4
SSr() = Array(6.51, 6.8, 6.9, 7#, 7.1, 7.1, 7.2, 7.2, 7.3, 7.3, 7.4, 7.4, 7.5,
7.5)
Case 5
SSr() = Array(5.7, 5.96, 6.11, 6.18, 6.26, 6.33, 6.4, 6.44, 6.5, 6.6, 6.6, 6.7,
6.7, 6.8)
Case 6
SSr() = Array(5.24, 5.51, 5.65, 5.73, 5.81, 5.88, 5.95, 6#, 6#, 6.1, 6.2, 6.2,
6.3, 6.3)
Case 7
SSr() = Array(4.95, 5.22, 5.37, 5.45, 5.53, 5.61, 5.69, 5.73, 5.8, 5.8, 5.9,
5.9, 6#, 6#)
Case 8
SSr() = Array(4.74, 5#, 5.14, 5.23, 5.32, 5.4, 5.47, 5.51, 5.5, 5.6, 5.7, 5.7,
5.8, 5.8)
Case 9
SSr() = Array(4.6, 4.86, 4.99, 5.08, 5.17, 5.25, 5.32, 5.36, 5.4, 5.5, 5.5, 5.6,
5.7, 5.7)
Case 10
SSr() = Array(4.48, 4.73, 4.88, 4.96, 5.06, 5.13, 5.2, 5.24, 5.28, 5.36, 5.42,
5.48, 5.54, 5.55)
Case 11
SSr() = Array(4.39, 4.63, 4.77, 4.86, 4.94, 5.01, 5.06, 5.12, 5.15, 5.24,
5.28, 5.34, 5.38, 5.39)
Case 12
SSr() = Array(4.32, 4.55, 4.68, 4.76, 4.84, 4.92, 4.96, 5.02, 5.07, 5.13, 5.17,
5.22, 5.24, 5.26)
Case 13
SSr() = Array(4.26, 4.48, 4.62, 4.69, 4.74, 4.84, 4.88, 4.94, 4.98, 5.04, 5.08,
5.13, 5.14, 5.15)
Case 14
SSr() = Array(4.21, 4.42, 4.55, 4.63, 4.7, 4.78, 4.83, 4.87, 4.91, 4.96, 5#,
5.04, 5.06, 5.07)
Case 15
SSr() = Array(4.17, 4.37, 4.5, 4.58, 4.64, 4.72, 4.77, 4.81, 4.84, 4.9, 4.94,
4.97, 4.99, 5#)
Case 16
SSr() = Array(4.13, 4.34, 4.45, 4.54, 4.6, 4.67, 4.72, 4.76, 4.79, 4.84, 4.88,
4.91, 4.93, 4.94)
Case 17
SSr() = Array(4.1, 4.3, 4.41, 4.5, 4.56, 4.63, 4.68, 4.72, 4.75, 4.8, 4.83,
4.86, 4.88, 4.89)
Case 18
SSr() = Array(4.07, 4.27, 4.38, 4.46, 4.53, 4.59, 4.64, 4.68, 4.71, 4.76, 4.79,
4.82, 4.84, 4.85)
Case 19
SSr() = Array(4.05, 4.24, 4.35, 4.43, 4.5, 4.56, 4.61, 4.64, 4.67, 4.72, 4.76,
4.79, 4.81, 4.82)
Case 20
SSr() = Array(4.02, 4.22, 4.33, 4.4, 4.47, 4.53, 4.58, 4.61, 4.65, 4.69, 4.73,
4.76, 4.78, 4.79)
Case 21, 22
SSr() = Array(3.99, 4.17, 4.28, 4.36, 4.42, 4.48, 4.53, 4.57, 4.6, 4.65, 4.68,
4.71, 4.74, 4.75)
Case 23, 24
SSr() = Array(3.96, 4.14, 4.24, 4.33, 4.39, 4.44, 4.49, 4.53, 4.57, 4.62, 4.64,
4.67, 4.7, 4.72)
Case 26, 26
SSr() = Array(3.93, 4.11, 4.21, 4.3, 4.36, 4.41, 4.46, 4.5, 4.53, 4.58, 4.62,
4.65, 4.67, 4.69)
Case 27, 28
SSr() = Array(3.91, 4.08, 4.18, 4.28, 4.34, 4.39, 4.43, 4.47, 4.51, 4.56, 4.6,
4.62, 4.65, 4.67)
Case 29, 30
SSr() = Array(3.89, 4.06, 4.16, 4.22, 4.32, 4.36, 4.41, 4.45, 4.48, 4.54,
4.58, 4.61, 4.63, 4.65)
Case 31 To 40
SSr() = Array(3.82, 3.99, 4.1, 4.17, 4.24, 4.3, 4.34, 4.37, 4.41, 4.46, 4.51,
4.54, 4.57, 4.59)
Case 41 To 60
SSr() = Array(3.76, 3.92, 4.03, 4.12, 4.17, 4.23, 4.27, 4.31, 4.34, 4.39, 4.44,
4.47, 4.5, 4.53)
Case 60 To 100
SSr() = Array(3.71, 3.86, 3.98, 4.06, 4.11, 4.17, 4.21, 4.25, 4.29, 4.35,
4.38, 4.42, 4.45, 4.48)
Case Is > 100
SSr() = Array(3.64, 3.8, 3.9, 3.98, 4.04, 4.09, 4.14, 4.17, 4.2, 4.26, 4.31,
4.34, 4.38, 4.41)
End Select
Case 0.05
Select Case idF
Case 1
SSr() = Array(18#, 18#, 18#, 18#, 18#, 18#, 18#, 18#, 18#, 18#, 18#, 18#,
18#, 18#)
Case 2
SSr() = Array(6.09, 6.09, 6.09, 6.09, 6.09, 6.09, 6.09, 6.09, 6.09, 6.09,
6.09, 6.09, 6.09, 6.09)
Case 3
SSr() = Array(4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5)
Case 4
SSr() = Array(3.93, 4.01, 4.02, 4.02, 4.02, 4.02, 4.02, 4.02, 4.02, 4.02, 4.02,
4.02, 4.02, 4.02)
Case 5
SSr() = Array(3.64, 3.74, 3.79, 3.83, 3.83, 3.83, 3.83, 3.83, 3.83, 3.83, 3.83,
3.83, 3.83, 3.83)
Case 6
SSr() = Array(3.46, 3.58, 3.64, 3.68, 3.68, 3.68, 3.68, 3.68, 3.68, 3.68,
3.68, 3.68, 3.68, 3.68)
Case 7
SSr() = Array(3.35, 3.47, 3.54, 3.58, 3.6, 3.61, 3.61, 3.61, 3.61, 3.61, 3.61,
3.61, 3.61, 3.61)
Case 8
SSr() = Array(3.26, 3.39, 3.47, 3.52, 3.55, 3.56, 3.56, 3.56, 3.56, 3.56, 3.56,
3.56, 3.56, 3.56)
Case 9
SSr() = Array(3.2, 3.34, 3.41, 3.47, 3.5, 3.52, 3.52, 3.52, 3.52, 3.52, 3.52,
3.52, 3.52, 3.52)
Case 10
SSr() = Array(3.15, 3.3, 3.37, 3.43, 3.46, 3.47, 3.47, 3.47, 3.47, 3.47, 3.47,
3.47, 3.47, 3.48)
Case 11
SSr() = Array(3.11, 3.27, 3.35, 3.39, 3.43, 3.44, 3.45, 3.46, 3.46, 3.46, 3.46,
3.46, 3.47, 3.48)
Case 12
SSr() = Array(3.08, 3.23, 3.33, 3.36, 3.4, 3.42, 3.44, 3.44, 3.46, 3.46, 3.46,
3.46, 3.47, 3.48)
Case 13
SSr() = Array(3.06, 3.21, 3.3, 3.35, 3.38, 3.41, 3.42, 3.44, 3.45, 3.45, 3.46,
3.46, 3.47, 3.47)
Case 14
SSr() = Array(3.03, 3.18, 3.27, 3.33, 3.37, 3.39, 3.41, 3.42, 3.44, 3.45, 3.46,
3.46, 3.47, 3.47)
Case 15
SSr() = Array(3.01, 3.16, 3.25, 3.31, 3.36, 3.38, 3.4, 3.42, 3.43, 3.44, 3.45,
3.46, 3.47, 3.47)
Case 16
SSr() = Array(3#, 3.15, 3.23, 3.3, 3.34, 3.37, 3.39, 3.41, 3.43, 3.44, 3.45,
3.46, 3.47, 3.47)
Case 17
SSr() = Array(2.98, 3.13, 3.22, 3.28, 3.33, 3.36, 3.38, 3.4, 3.42, 3.44, 3.45,
3.46, 3.47, 3.47)
Case 18
SSr() = Array(2.97, 3.12, 3.21, 3.27, 3.32, 3.35, 3.37, 3.39, 3.41, 3.43, 3.45,
3.46, 3.47, 3.47)
Case 19
SSr() = Array(2.96, 3.11, 3.19, 3.26, 3.31, 3.35, 3.37, 3.39, 3.41, 3.43, 3.44,
3.46, 3.47, 3.47)
Case 20
SSr() = Array(2.95, 3.1, 3.18, 3.25, 3.3, 3.34, 3.36, 3.38, 3.4, 3.43, 3.44,
3.46, 3.46, 3.47)
Case 21, 22
SSr() = Array(2.93, 3.08, 3.17, 3.24, 3.29, 3.32, 3.35, 3.37, 3.39, 3.42, 3.44,
3.45, 3.46, 3.47)
Case 23, 24
SSr() = Array(2.92, 3.07, 3.15, 3.22, 3.28, 3.31, 3.34, 3.37, 3.38, 3.41, 3.44,
3.45, 3.46, 3.47)
Case 26, 26
SSr() = Array(2.91, 3.06, 3.14, 3.21, 3.27, 3.3, 3.34, 3.36, 3.38, 3.41, 3.43,
3.45, 3.46, 3.47)
Case 27, 28
SSr() = Array(2.9, 3.04, 3.13, 3.2, 3.26, 3.3, 3.33, 3.35, 3.37, 3.4, 3.43,
3.45, 3.46, 3.47)
Case 29, 30
SSr() = Array(2.89, 3.04, 3.12, 3.2, 3.25, 3.29, 3.32, 3.35, 3.37, 3.4, 3.43,
3.44, 3.46, 3.47)
Case 31 To 40
SSr() = Array(2.86, 3.01, 3.1, 3.17, 3.22, 3.27, 3.3, 3.33, 3.35, 3.39, 3.42,
3.44, 3.46, 3.47)
Case 41 To 60
SSr() = Array(2.83, 2.98, 3.08, 3.14, 3.2, 3.24, 3.28, 3.31, 3.33, 3.37, 3.4,
3.43, 3.45, 3.47)
Case 60 To 100
SSr() = Array(2.8, 2.95, 3.05, 3.12, 3.18, 3.22, 3.26, 3.29, 3.32, 3.36, 3.4,
3.42, 3.45, 3.47)
Case Is > 100
SSr() = Array(2.77, 2.92, 3.02, 3.09, 3.15, 3.19, 3.23, 3.26, 3.29, 3.34, 3.38,
3.41, 3.44, 3.47)
End Select
Case Else
modMessage = "本部件当前仅支持 0.05 及 0.01 两种显著性!"
DuncanSSR = caiCancel
Exit Function
End Select
' Assign SSR values to dSSR() for return according to iSize
iT = IIf(iSize < 10, iSize, 10)
For I = 1 To iT - 1
dSSR(I) = SSr(I)
' Note! SSR(1) corresponding to Size=2, SSR(2) --- Size=3 !!
Next
If iSize > 10 Then
' Note: SSR(10) corresponding to Size 12, SSR(11) --- Size 14, ...... ! i.e. SSR*iT) --- Size
Sz(iT) !
iT = 10
For I = 10 To iSize - 1
While Sz(iT) < I + 1
' since SSR(i) corresponding to Size=I+1 !!!
iT = iT + 1
Wend
dSSR(I) = SSr(iT)
Next I
End If
DuncanSSR = caiOK
Exit Function
SSRFail:
modMessage = "检索多重比较 Duncan SSR 值时出错!错误号:" & Err.Number & vbCrLf _
& "说明:" & Err.Description
DuncanSSR = caiError
End Function
' 返回“方差同质性查验的 Cochran 法(Testing the Equality of Variances according to Cochran)”
的关键值 G(iSize, idF),其中
' iSize -- 参加检验的方差个数; idF -- 每个方差的样本自由度;dAlpha -- 显著性,必须
为 0.05 或 0.01。
' Refer to: "Applied Stastistics (2nd. Edition)" by Lothar Sachs, P.497
Function CochranTab(iSize As Integer, idF As Integer, dAlpha) As Double
Dim I As Integer
Dim CochranV() As Variant, dFs() As Variant
dFs() = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 16, 36, 144, 999999)
I=1
Do While (idF > dFs(I))
I=I+1
Loop
Select Case dAlpha
Case 0.05
Select Case iSize
Case 2
CochranV() = Array(0.9985, 0.975, 0.9392, 0.9057, 0.8772, 0.8534,
0.8332, 0.8159, 0.801, 0.788, 0.7341, 0.6602, 0.5813, 0.5)
Case 3
CochranV() = Array(0.9669, 0.8709, 0.7977, 0.7457, 0.7071, 0.6771,
0.653, 0.6333, 0.6167, 0.6025, 0.5466, 0.4748, 0.4031, 0.3333)
Case 4
CochranV() = Array(0.9065, 0.7679, 0.6841, 0.6287, 0.5895, 0.5598,
0.5365, 0.5175, 0.5017, 0.4884, 0.4366, 0.372, 0.3093, 0.25)
Case 5
CochranV() = Array(0.8412, 0.6838, 0.5981, 0.5441, 0.5065, 0.4783,
0.4564, 0.4387, 0.4241, 0.4118, 0.3645, 0.3066, 0.2513, 0.2)
Case 6
CochranV() = Array(0.7808, 0.6161, 0.5321, 0.4803, 0.4447, 0.4184,
0.398, 0.3817, 0.3682, 0.3568, 0.3135, 0.2612, 0.2119, 0.1667)
Case 7
CochranV() = Array(0.7271, 0.5612, 0.48, 0.4307, 0.3974, 0.3726, 0.3535,
0.3384, 0.3259, 0.3154, 0.2756, 0.2278, 0.1833, 0.1429)
Case 8
CochranV() = Array(0.6798, 0.5157, 0.4377, 0.391, 0.3595, 0.3362,
0.3185, 0.3043, 0.2926, 0.2829, 0.2462, 0.2022, 0.1616, 0.125)
Case 9
CochranV() = Array(0.6385, 0.4775, 0.4027, 0.3584, 0.3286, 0.3067,
0.2901, 0.2768, 0.2659, 0.2568, 0.2226, 0.182, 0.1446, 0.1111)
Case 10
CochranV() = Array(0.602, 0.445, 0.3733, 0.3311, 0.3029, 0.2823, 0.2666,
0.2541, 0.2439, 0.2353, 0.2032, 0.1655, 0.1308, 0.1)
Case 11, 12
CochranV() = Array(0.541, 0.3924, 0.3264, 0.288, 0.2624, 0.2439, 0.2299,
0.2187, 0.2098, 0.202, 0.1737, 0.1403, 0.11, 0.0833)
Case 13 To 15
CochranV() = Array(0.4709, 0.3346, 0.2758, 0.2419, 0.2195, 0.2034,
0.1911, 0.1815, 0.1736, 0.1671, 0.1429, 0.1144, 0.0889, 0.0667)
Case 16 To 20
CochranV() = Array(0.3894, 0.2705, 0.2205, 0.1921, 0.1735, 0.1602,
0.1501, 0.1422, 0.1357, 0.1303, 0.1108, 0.0879, 0.0675, 0.05)
Case 21 To 24
CochranV() = Array(0.3434, 0.2354, 0.1907, 0.1656, 0.1493, 0.1374,
0.1286, 0.1216, 0.116, 0.1113, 0.0942, 0.0743, 0.0567, 0.0417)
Case 25 To 30
CochranV() = Array(0.2929, 0.198, 0.1593, 0.1377, 0.1237, 0.1137,
0.1061, 0.1002, 0.0958, 0.0921, 0.0771, 0.0604, 0.0457, 0.0333)
Case 31 To 40
CochranV() = Array(0.237, 0.1576, 0.1259, 0.1082, 0.0968, 0.0887,
0.0827, 0.078, 0.0745, 0.0713, 0.0595, 0.0462, 0.0347, 0.025)
Case Else
modMessage = "本表不支持参试组个数大于 40 的情形!" _
& vbCrLf & "(同质检验 Cochran 法一般仅应用于参试的方差数不
大于 10 的情形。
)"
CochranTab = caiError
Exit Function
End Select
Case 0.01
Select Case iSize
Case 2
CochranV() = Array(0.9999, 0.995, 0.9794, 0.9586, 0.9373, 0.9172,
0.8988, 0.8823, 0.8674, 0.8539, 0.7949, 0.7067, 0.6062, 0.5)
Case 3
CochranV() = Array(0.9933, 0.9423, 0.8831, 0.8335, 0.7933, 0.7606,
0.7335, 0.7107, 0.6912, 0.6743, 0.6059, 0.5153, 0.423, 0.3333)
Case 4
CochranV() = Array(0.9676, 0.8643, 0.7814, 0.7212, 0.6761, 0.641,
0.6129, 0.5897, 0.5702, 0.5536, 0.4884, 0.4057, 0.3251, 0.25)
Case 5
CochranV() = Array(0.9279, 0.7885, 0.6957, 0.6329, 0.5875, 0.5531,
0.5259, 0.5037, 0.4854, 0.4697, 0.4094, 0.3351, 0.2644, 0.2)
Case 6
CochranV() = Array(0.8828, 0.7218, 0.6258, 0.5635, 0.5195, 0.4866,
0.4608, 0.4401, 0.4229, 0.4084, 0.3529, 0.2858, 0.2229, 0.1667)
Case 7
CochranV() = Array(0.8376, 0.6644, 0.5685, 0.508, 0.4659, 0.4347,
0.4105, 0.3911, 0.3751, 0.3616, 0.3105, 0.2494, 0.1929, 0.1429)
Case 8
CochranV() = Array(0.7945, 0.6152, 0.5209, 0.4627, 0.4226, 0.3932,
0.3704, 0.3522, 0.3373, 0.3248, 0.2779, 0.2214, 0.17, 0.125)
Case 9
CochranV() = Array(0.7544, 0.5727, 0.481, 0.4251, 0.387, 0.3592, 0.3378,
0.3207, 0.3067, 0.295, 0.2514, 0.1992, 0.1521, 0.1111)
Case 10
CochranV() = Array(0.7175, 0.5358, 0.4469, 0.3934, 0.3572, 0.3308,
0.3106, 0.2945, 0.2813, 0.2704, 0.2297, 0.1811, 0.1376, 0.1)
Case 11, 12
CochranV() = Array(0.6528, 0.4751, 0.3919, 0.3428,
0.268, 0.2535, 0.2419, 0.232, 0.1961, 0.1535, 0.1157, 0.0833)
Case 13 To 15
CochranV() = Array(0.5747, 0.4069, 0.3317, 0.2882,
0.2228, 0.2104, 0.2002, 0.1918, 0.1612, 0.1251, 0.0934, 0.0667)
Case 16 To 20
CochranV() = Array(0.4799, 0.3297, 0.2654, 0.2288,
0.1748, 0.1646, 0.1567, 0.1501, 0.1248, 0.096, 0.0709, 0.05)
Case 21 To 24
CochranV() = Array(0.4247, 0.2871, 0.2295, 0.197,
0.1495, 0.1406, 0.1338, 0.1283, 0.106, 0.081, 0.0595, 0.0417)
Case 25 To 30
CochranV() = Array(0.3632, 0.2412, 0.1913, 0.1635,
0.1232, 0.1157, 0.11, 0.1054, 0.0867, 0.0658, 0.048, 0.0333)
Case 31 To 40
CochranV() = Array(0.294, 0.1915, 0.1508, 0.1281,
0.0957, 0.0898, 0.0853, 0.0816, 0.0668, 0.0503, 0.0363, 0.025)
Case Else
0.3099, 0.2861,
0.2593, 0.2386,
0.2048, 0.1877,
0.1759, 0.1608,
0.1454, 0.1327,
0.1135, 0.1033,
modMessage = "本表不支持参试组个数大于 40 的情形!" _
& vbCrLf & "(同质检验 Cochran 法一般仅应用于参试的方差数不
大于 10 的情形。
)"
CochranTab = caiError
Exit Function
End Select
Case Else
modMessage = "本部件当前仅支持 0.05 及 0.01 两种显著性!"
CochranTab = caiCancel
Exit Function
End Select
CochranTab = CochranV(I)
End Function
' 根据给定的自由度 idF 及α值(仅限于 0.05 及 0.01,否则返回负数)返回对应的卡方值
X_Square
' 数据来自 P.6:5. X_Square 分布的上侧分位数表
Function XSquareTab(idF As Integer, dAlpha As Double) As Double
Dim XValues() As Variant
If idF > 30 Then
modMessage = "本卡方表支持的最大自由度值为 30!"
XSquareTab = caiError
Exit Function
End If
Select Case dAlpha
Case 0.05
XValues() = Array(3.841, 5.991, 7.815, 9.488, 11.07, 12.592, 14.067, 15.507, 16.919,
18.307, 19.675, 21.026, 22.362, 23.685, 24.996, _
26.296, 27.587, 28.869, 30.144, 31.41, 32.671, 33.924, 35.172,
36.415, 37.652, 38.885, 40.113, 41.337, 42.557, 43.773)
Case 0.01
XValues() = Array(6.635, 9.21, 11.345, 12.277, 15.068, 16.812, 18.475, 20.09,
21.666, 23.209, 24.725, 26.217, 27.688, 29.141, 30.578, _
32#, 33.409, 34.805, 36.191, 37.566, 38.932, 40.289, 41.638,
42.98, 44.314, 45.642, 46.963, 48.278, 49.588, 50.892)
Case Else
modMessage = "本部件当前仅支持 0.05 及 0.01 两种显著性!"
XSquareTab = caiCancel
Exit Function
End Select
XSquareTab = XValues(idF)
End Function
' 根据给定的自由度 idF 及α值(仅限于 0.05 及 0.01,否则返回负数)返回对应的 Ra 值
'
它是检验两个统计量是否相关的临界值
' 数据来自 P.18:12. 检验相关系数=0 的临界值 Ra 表
Function RaTab(idF As Integer, dAlpha As Double) As Double
Dim I As Integer
Dim RaVals() As Variant, dFs() As Variant
If idF > 100 Then
modMessage = "本 Ra 表支持的最大自由度值为 100!"
RaTab = caiError
Exit Function
End If
dFs() = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, _
25, 30, 35, 40, 45, 50, 60, 70, 80, 90, 100)
I=1
Do While (idF > dFs(I))
I=I+1
Loop
Select Case dAlpha
Case 0.05
RaVals() = Array(0.99692, 0.95, 0.8783, 0.8114, 0.7545, 0.7067, 0.6664, 0.6319,
0.6021, 0.576, _
0.5529, 0.5324, 0.5139, 0.4973, 0.4821, 0.4683, 0.4555,
0.4438, 0.4329, 0.4227, _
0.3809, 0.3494, 0.3246, 0.3044, 0.2875, 0.2732, 0.25,
0.2319, 0.2172, 0.205, 0.1946)
Case 0.01
RaVals() = Array(0.999877, 0.99, 0.95873, 0.9172, 0.8745, 0.8343, 0.7977, 0.7646,
0.7348, 0.7079, _
0.6835, 0.6614, 0.6411, 0.6226, 0.6055, 0.5897, 0.5751,
0.5614, 0.5487, 0.5368, _
0.4869, 0.4487, 0.4182, 0.3932, 0.3721, 0.3541, 0.3248,
0.3017, 0.283, 0.2673, 0.254)
Case Else
modMessage = "本部件当前仅支持 0.05 及 0.01 两种显著性!"
RaTab = caiCancel
Exit Function
End Select
RaTab = RaVals(I)
End Function
类模块 clsStatisAnova.cls
Option Explicit
Option Base 1
' **********************************************************************
' 本 Class 符合 COM 设计规范,可提供方差分析服务:包括单因子、双因
' 子 (三因子?)方差分析。原始数据(Float-32)需以多维数组的形式
' 提供(单因子的为二维,双因子的为三维)。当原始数据不完整时,
' 相应的数组项必须赋值为 cNonSense,当前定义为 -9999 !
' **********************************************************************
'=======================================================================
' Define two Custom Types publicly
'=======================================================================
' Define a Type for store the Statistic Values of Anova Analysis
Public Type AnovaStatis
' 自由度
dFt As Integer
' Degrees of Freedom -- Total
dFa As Integer
' ......
-- Factor A, e.g. the "Test Sites"
dFb As Integer
dFr As Integer
dFab As Integer
dFerr As Integer
' 平方和
SSt As Double
' Total Square Sum of (Xijk-Average(Xijk))
SSa As Double
' Total Squire Sum about the First Factor A, e.g. the "Test Sites"
SSb As Double
' ...... , e.g. "Varieties"
SSr As Double
' ...... , e.g. "Blocks"
SSab As Double
' ...... about "Cross Effections"
SSerr As Double
' ...... about "Experimental Error"
GrandMean As Double ' Mean Value of all Samples
' F 值及对应的概率(显著性)
FVr As Double
' F Value from Repitations inside factor A. (来自试点内区组);
(SSr/dFr)/(SSerr/dFerr)
=
FVb As Double
' F Value from factor B, e.g. Varieties. (来自品种);
' =(SSb/dFb)/Deno, here Deno=(SSab/dFab) if
in Radomized mode or =(SSerr/dFerr) if Fixed mode
FVa As Double
=(SSa/dFa)/(SSerr/dFerr)
' F Value from factor A, e.g. Test Sites.
FVab As Double
' F Value from the iteraction of factor A and B.
=(SSab/dFab)/(SSerr/dFerr)
FPr As Double
' Corresponding significense ......
FPb As Double
FPa As Double
FPab As Double
End Type
( 来 自 试 点 );
(来自试点 x 品种);
' to store the Result of Multiple Comparision for each Group that presents in MC analysis
' i.e. the whole result should be stored in an Array of this type and the groups should ordered
descendly
Public Type MCReport
Index As Integer
' the group correspondint to the IndexTh. member (Counted from 1) in
the original resource array
Mean As Double
' mean value of the group
Classif As String
' the classifications of the group. its size always=20, with the 1st 10 chars contain _
the classification for 0.05 Significance, the last 10, 0.01 Significance, e.g. "
cde
DE
"
End Type
' to store the result of Equality Test for the Variances
Public Type EqualityResult
MethodName As String
' either "Cochran" or "Bartlette"
Result As Integer
' < 0 -- Test Failed, means other members are
meanless; >= 0 -- Test Successfully completed:
' here, 0 -- Equlity Accepted, 1 -- Equlity Rejected on 0.05 Significance,
2 -- Rejected on 0.01 Significance;
Size As Integer
' Number of Variances presented in Test
dF As Integer
' the Degree of Freedom of each Variance
EvalValue As Double
' Evaluated Value, i.e. "G_max" for Cochran, "X_eq" for
Bartlette
CritVal005 As Double
' the Critical Value on 0.05 Significance found from Table:
Cochran Table or X_Square Table
CritVal001 As Double
' the Critical Value on 0.01 Significance found from Table:
Cochran Table or X_Square Table
End Type
' to store the result of Regresion Analysis
Public Type RegresionResult
Result As Integer
' < 0 -- Test Failed, means other members are meanless;
>= 0 -Test Successfully completed:
' here, 0 -- Independency (ρ=0) Accepted, 1 -- Independency Rejected on 0.05
Significance, 2 -- Rejected on 0.01 Significance;
Size As Integer
' Number of Samples, i.e. (Xi, Yi)s, presented in Test
Slope As Double
' Formular: Y=k*X + b, the value of k
Intercept As Double
' the value of b
CorCorf As Double
' Correlative Corefficient between X and Y, evaluated from Sample
Data (Xi, Yi)
CritRa005 As Double
' the Critical Value on 0.05 Significance found from RA Table for
Independency Test
CritRa001 As Double
' the Critical Value on 0.01 Significance found from RA Table for
Independency Test
End Type
'==============================================================================
==========================================
' current states of Anova analysis
Private mAnovaResultState As Integer
' 0 -- Initial State, mAnovaResult contains no valid information ; <0 -- Error happened,
analysisi failed
' 10+i -- mAnovaResult contains the results of Anova1; 20 + i -- the results of Anova2
' here, i=1 -- .SS*s, .dF*s and correponding Array T*s() are valid,
'
i=2 -- F Test finished, all members of mAnovaResult are Valid
' 本部件把 Anova2 分成两种类型: 区试(一年多点)联合方差分析; 双因子随机区组试验. 每
种
' 类型又可对其因子选择固定/随机模式, 这些信息就存储在这里
Private mAnova2Mode As Integer
' 1 -- 联合分析, A(试点)固定; 2 -- 联合分析, A(试点)随机;
' 11 -- 随机区组, A, B 都固定; 12 -- 随机区组, A 固定, B 随机;
'
13 -- 随机区组, A 随机, B 固定; 14 -- 随机区组, A,B 都随机.
Private mDataState As Integer
' =0: mData() contains no valid source data;
' >0: contains the valid Samples Data, and represents the dimention of mData()
' <0: contains the valid data to do some type of analysisi, e.g. Equality, Multiple Comparesion,
etc., _
|mDim| represents the dimention of mData().
'
Note: after runing Anova1WSD(), mDataState = -3
' Source Data for analyzing
Private mData() As Single
' the result of Anova Analysis
Private mAnovaResult As AnovaStatis
' The detail information that the Object want to return to the client (Caller)
Private mMessage As String
' the normal Report of Anova Analysis for Crop Reginal Test
Private mMCompReport() As MCReport
' mVRData() is to store the Variance of each Group that takes part in Equlity Test.
' It may also be used as 2 Dimentional (Xi, Yi) to store the Sample data for Regression Analysis
' The Data stored in original order and may not be sorted yet.
Private mVRData() As Double
Private mVRDataState As Integer
' =0: mVRData() contains no valid data;
=1: contains Variances;
' =2 contains (Xi, Yi)s for Regression Analysis.
Private mEqTestResult As EqualityResult
Private mRegresResult As RegresionResult
' store some middle clclating results to be shared among methods of the class
Private T1() As Double, T2() As Double, T31() As Double, X21() As Double
' Store the index of Factor A, only valid during Anova1 Analysis and its related Tests, i.e. it
indicates that
' the Sample Data currently used by Anova1 are stored in mData(mIdxA, *, *) !
Private mIdxA As Integer
' ********************************************************************
' Define properties for readonly accessing the members of the class
' ********************************************************************
Public Property Get iAnovaResultState() As Integer
iAnovaResultState = mAnovaResultState
End Property
Public Property Get ctAnovaResult() As AnovaStatis
ctAnovaResult = mAnovaResult
End Property
Public Property Get strMessage() As String
strMessage = mMessage
End Property
' ref to. "Putting Property Procedures to Work for You", a section in "Programming with Object"
' of <Programmer's Guide>, MSDN Lib, <Using Visual Basic>.
Public Property Get ctMCompReport(Index As Integer) As MCReport
' Should do some check of the value of Index for reliability here
ctMCompReport = mMCompReport(Index)
End Property
Public Property Get dVariances(Index As Integer) As Double
If mVRDataState = 1 Then
If Index > 0 And Index <= UBound(mVRData) Then
dVariances = mVRData(Index)
Else
dVariances = cNonSense
End If
Else
dVariances = cNonSense
End If
End Property
Public Property Get ctEqTestResult() As EqualityResult
ctEqTestResult = mEqTestResult
End Property
Public Property Get dXYSamples(I As Integer, J As Integer) As Double
If mVRDataState = 2 Then
If I > 0 And I < 3 And J > 0 And J <= UBound(mVRData, 2) Then
dXYSamples = mVRData(I, J)
Else
dXYSamples = cNonSense
End If
Else
dXYSamples = cNonSense
End If
End Property
Public Property Get ctRegresResult() As RegresionResult
ctRegresResult = mRegresResult
End Property
'
*******************************************************************************
******
' Private Routines for internal use
'
*******************************************************************************
******
' Initialize mAnovaResult and release the momory ocupied by Dynamic Arrys and
mMCCompREport
Private Sub InitResults()
Dim Item As Variant
With mAnovaResult
.dFa = 0: .dFab = 0: .dFb = 0: .dFerr = 0: .dFr = 0: .dFt = 0
.SSa = 0: .SSab = 0: .SSb = 0: .SSerr = 0: .SSr = 0: .SSt = 0
.FPa = 0: .FPab = 0: .FPb = 0: .FPr = 0: .FVa = 0: .FVab = 0: .FVb = 0: .FVr = 0
.GrandMean = 0
End With
mIdxA = -1
ReDim T1(1), T2(1), T31(1), X21(1)
ReDim mMCompReport(1)
End Sub
' Check the Array of Sopurce Data for Anova Analysis and assign it to mData()
' Return the number of dimentions of mData() if successed
Private Function CheckAnovaSourceData(ByRef sData() As Single, ByVal iDim As Integer) As
Integer
' iDim -- the dimention of Source Data
Dim n1 As Integer, n2 As Integer, n3 As Integer
Dim I As Integer, J As Integer, k As Integer, iT As Integer
Dim sT As Single
On Error GoTo DataErr
n1 = UBound(sData, 1) - LBound(sData, 1) + 1
If n1 < 2 Then
mMessage = "因子 A 的样本数小于 2,"
CheckAnovaSourceData = caiCancel
Exit Function
End If
If iDim > 1 Then
n2 = UBound(sData, 2) - LBound(sData, 2) + 1
If n2 < 2 Then
If iDim = 1 Then
mMessage = "样本无重复,本系统暂无法分析!"
Else
mMessage = "因子 B 的样本数小于 2,"
End If
CheckAnovaSourceData = caiCancel
Exit Function
End If
End If
If iDim > 2 Then
n3 = UBound(sData, 3) - LBound(sData, 3) + 1
If n3 < 2 Then
mMessage = "样本无重复,本系统暂无法分析!"
CheckAnovaSourceData = caiCancel
Exit Function
End If
End If
Select Case iDim
Case 1
ReDim mData(n1)
For I = 1 To n1
sT = sData(I + LBound(sData) - 1)
If sT = cNonSense Then
mMessage = "所提供的原始数据不平衡或有缺值,目前版本暂不
能对此进行方差分析!"
mDataState = 0
CheckAnovaSourceData = caiCancel
Exit Function
End If
mData(I) = sT
Next I
iT = 1
Case 2
ReDim mData(1, n1, n2)
' Add the 1st dimention to make Anova analysis for RCB (Single Site) more
consistent with the analysis for Combined (Single yera, Multiple Sites)
'?1
For I = 1 To n1
For J = 1 To n2
sT = sData(I + LBound(sData, 1) - 1, J + LBound(sData, 2) - 1)
If sT = cNonSense Then
mMessage = "所提供的原始数据不平衡或有缺值,目前版本暂不
能对此进行方差分析!"
mDataState = 0
CheckAnovaSourceData = caiCancel
Exit Function
End If
mData(1, I, J) = sT
Next J
Next I
iT = 3
Case 3
ReDim mData(n1, n2, n3)
For I = 1 To n1
For J = 1 To n2
For k = 1 To n3
sT = sData(I + LBound(sData, 1) - 1, J + LBound(sData, 2) - 1, k +
LBound(sData, 3) - 1)
If sT < 0 Then
mMessage = "所提供的原始数据不平衡或有缺值,目前版本
暂不能处理此类数据,"
mDataState = 0
CheckAnovaSourceData = caiCancel
Exit Function
End If
mData(I, J, k) = sT
Next k
Next J
Next I
iT = 3
Case Else
mMessage = "目前版仅支持三维及以下的样本数据,抱歉!"
mDataState = 0
CheckAnovaSourceData = caiCancel
Exit Function
End Select
mDataState = iT
CheckAnovaSourceData = iT
Exit Function
DataErr:
mMessage = "所提供的原始数据数组的维数不符合要求,"
mDataState = caiError
CheckAnovaSourceData = caiError
End Function
' Calclating Statistic Values needed for Anova1 Analysis
' idxA is to indicate that the source data are mData(idxA, *, *)
Private Function CalcSSdFs1(idxA As Integer) As Integer
Dim n2 As Integer, n3 As Integer
Dim J As Integer, k As Integer
Dim dCF As Double
Dim dTemp As Double
On Error GoTo Calc1Fail
' get the size of each dimention of the source data
n2 = UBound(mData, 2)
n3 = UBound(mData, 3)
' Calclating the Degrees of Feedom
With mAnovaResult
.dFt = n2 * n3 - 1
.dFb = n2 - 1
.dFr = n3 - 1
.dFerr = .dFt - .dFb - .dFr
End With
' Calclating Sumary of Squiares
ReDim T2(n2), T31(n3)
dCF = 0
dTemp = 0
For J = 1 To n2
T2(J) = 0
For k = 1 To n3
dCF = dCF + mData(idxA, J, k)
dTemp = dTemp + mData(idxA, J, k) * mData(idxA, J, k)
T2(J) = T2(J) + mData(idxA, J, k)
Next k
Next J
mAnovaResult.GrandMean = dCF / (n2 * n3)
dCF = dCF * dCF / (n2 * n3)
mAnovaResult.SSt = dTemp - dCF
dTemp = 0
For J = 1 To n2
dTemp = dTemp + T2(J) * T2(J)
Next J
mAnovaResult.SSb = dTemp / n3 - dCF
For k = 1 To n3
T31(k) = 0
For J = 1 To n2
T31(k) = T31(k) + mData(idxA, J, k)
Next J
Next k
dTemp = 0
For k = 1 To n3
dTemp = dTemp + T31(k) * T31(k)
Next k
With mAnovaResult
.SSr = dTemp / n2 - dCF
.SSerr = .SSt - .SSb - .SSr
If .SSerr = 0 Then
mMessage = "计算发现来自试验误差的变异的平方和为 0!无法对该样本数据
作统计分析处理"
CalcSSdFs1 = caiCancel
Exit Function
End If
End With
CalcSSdFs1 = caiOK
Exit Function
Calc1Fail:
mMessage = "计算平方和时出错!错误号:" & Err.Number & vbCrLf _
& "说明:" & Err.Description
CalcSSdFs1 = caiError
End Function
' Calclating Statistic Values needed for Anova2 Analysis
Private Function CalcSSdFs2() As Integer
Dim n1 As Integer, n2 As Integer, n3 As Integer
Dim I As Integer, J As Integer, k As Integer
Dim dCF As Double
Dim iC As Integer, dTemp As Double
On Error GoTo Calc2Fail
' get the size of each dimention of the source data
n1 = UBound(mData, 1)
n2 = UBound(mData, 2)
n3 = UBound(mData, 3)
' Calclating the Degrees of Feedom
With mAnovaResult
.dFt = n1 * n2 * n3 - 1
.dFa = n1 - 1
.dFb = n2 - 1
.dFr = n1 * (n3 - 1)
.dFab = (n1 - 1) * (n2 - 1)
.dFerr = .dFt - .dFa - .dFb - .dFr - .dFab
End With
' Calclating Sumary of Squiares
ReDim T1(n1), T2(n2), T31(n3 * n1), X21(n2, n1)
' T2=? (tv=?):
"T*v*", means total of all Sides and Repititions for each Variety
For I = 1 To n2
T2(I) = 0
For J = 1 To n1
For k = 1 To n3
T2(I) = T2(I) + mData(J, I, k)
Next k
Next J
Next I
' T31=? (Tkj=?): "Ta*r", means Total of all Varieties for eash Site's each Repitation
iC = 0
For J = 1 To n1
For k = 1 To n3
iC = iC + 1
T31(iC) = 0
For I = 1 To n2
T31(iC) = T31(iC) + mData(J, I, k)
Next I
Next k
Next J
' T1=?
' T1 :
dCF=? (tj=?,cf=?)
Ta**, means Total of all Varieties and Repititions for each Site, i.e. of all plots in each
Site
dCF = 0
For I = 1 To n1
T1(I) = 0
For J = 1 To n2
For k = 1 To n3
T1(I) = T1(I) + mData(I, J, k)
dCF = dCF + mData(I, J, k)
Next k
Next J
Next I
mAnovaResult.GrandMean = dCF / (n1 * n2 * n3)
dCF = dCF * dCF / (n1 * n2 * n3)
' SSt=?
dTemp = 0
For I = 1 To n1
For J = 1 To n2
For k = 1 To n3
dTemp = dTemp + mData(I, J, k) * mData(I, J, k)
Next k
Next J
Next I
mAnovaResult.SSt = dTemp - dCF
' SSa=? (sse=?)
dTemp = 0
For I = 1 To n1
dTemp = dTemp + T1(I) * T1(I)
Next I
mAnovaResult.SSa = dTemp / (n3 * n2) - dCF
' SSb=? (ssg=?)
dTemp = 0
For I = 1 To n2
dTemp = dTemp + T2(I) * T2(I)
Next I
mAnovaResult.SSb = dTemp / (n3 * n1) - dCF
' SSr=? (ssre=?)
dTemp = 0
If mAnova2Mode <= 10 Then
' 区试联合分析型, 计算来自试点内区组间的变异
For I = 1 To n3 * n1
dTemp = dTemp + T31(I) * T31(I)
Next I
dTemp = dTemp / n2
mAnovaResult.SSr = dTemp - mAnovaResult.SSa - dCF
' can be proved mathematically !
Else ' 随机区组试验, 计算来自区组间的变异(对因子 A 的不同处理水平同等对待)
mAnovaResult.SSr = 0
For k = 1 To n3
dTemp = 0
For I = 0 To n1 - 1
dTemp = dTemp + T31(I * n3 + k)
Next I
mAnovaResult.SSr = mAnovaResult.SSr + dTemp * dTemp
Next k
mAnovaResult.SSr = mAnovaResult.SSr / (n1 * n2) - dCF
End If
' X21(I,J)=? (x(i,j)=?) Note: the 1st Dimention is for Factor B, Varieties!
For I = 1 To n2
For J = 1 To n1
X21(I, J) = 0
For k = 1 To n3
X21(I, J) = X21(I, J) + mData(J, I, k)
Next k
Next J
Next I
' SSab=? ( ssge=?)
dTemp = 0
For I = 1 To n1
For J = 1 To n2
dTemp = dTemp + X21(J, I) * X21(J, I)
'
X21(J, I) = X21(J, I) / n3 ' Now, it is the Average of mData(i, j, *)
Next J
Next I
With mAnovaResult
.SSab = dTemp / n3 - .SSa - .SSb - dCF
.SSerr = .SSt - .SSa - .SSb - .SSr - .SSab
If .SSerr = 0 Then
mMessage = "计算发现来自试验误差的变异的平方和为 0!无法对该样本数据
作统计分析处理"
CalcSSdFs2 = caiCancel
Exit Function
End If
If .SSab = 0 And (mAnova2Mode = 2 Or mAnova2Mode > 11) Then
mMessage = "计算发现来自因子 A、B 间互作的变异的平方和为 0!" _
& "要对该样本数据作方差分析,只能把在 A、B 设为固定模式。 "
CalcSSdFs2 = caiCancel
Exit Function
End If
End With
CalcSSdFs2 = caiOK
Exit Function
Calc2Fail:
mMessage = "计算平方和时出错!错误号:" & Err.Number & vbCrLf _
& "说明:" & Err.Description
CalcSSdFs2 = caiError
End Function
' Calclating F Valus and corresponding probablities/Significances for Anova1 Analysis
' Radomized mode only
Private Function CalcAnova1Fs() As Integer
Dim MSb As Double, MSr As Double, MSerr As Double
' Calclating MSs
With mAnovaResult
MSb = .SSb / .dFb
MSr = .SSr / .dFr
MSerr = .SSerr / .dFerr
End With
' Calclating F Values and thier probablities
With mAnovaResult
.FVr = MSr / MSerr
.FVb = MSb / MSerr
.FPr = Ftest(.dFr, .dFerr, .FVr)
.FPb = Ftest(.dFb, .dFerr, .FVb)
End With
CalcAnova1Fs = caiOK
End Function
' Calclating F Valus and corresponding probablities/Significances for Anova2 Analysis
Private Function CalcAnova2Fs() As Integer
Dim MSa As Double, MSb As Double, MSr As Double, MSab As Double, MSerr As Double
' Calclating MSs
With mAnovaResult
MSa = .SSa / .dFa
MSb = .SSb / .dFb
MSab = .SSab / .dFab
MSr = .SSr / .dFr
MSerr = .SSerr / .dFerr
End With
' Calclating F Values and thier probablities
With mAnovaResult
Select Case mAnova2Mode
Case 1, 2, 11, 13
.FVa = MSa / MSerr
.FPa = Ftest(.dFa, .dFerr, .FVa)
Case 12, 14
.FVa = MSa / MSab
.FPa = Ftest(.dFa, .dFab, .FVa)
End Select
Select Case mAnova2Mode
Case 1, 11, 12
.FVb = MSb / MSerr
.FPb = Ftest(.dFb, .dFerr, .FVb)
Case 2, 13, 14
.FVb = MSb / MSab
.FPb = Ftest(.dFb, .dFab, .FVb)
End Select
.FVr = MSr / MSerr
.FVab = MSab / MSerr
.FPr = Ftest(.dFr, .dFerr, .FVr)
.FPab = Ftest(.dFab, .dFerr, .FVab)
End With
CalcAnova2Fs = caiOK
End Function
' Anova1 Analysisi. idxA indicate what part of mData(), i.e. mData(idxA,*,*), should be used as
the Sample Data
Private Function Anova1Calc(idxA As Integer) As Integer
Dim iT As Integer
If mDataState <= 0 Then
mMessage = "没收到有效的原始样本数据,无法进行单因子方差分析!"
mAnovaResultState = 0
Anova1Calc = caiCancel
Exit Function
End If
If idxA < 1 Or idxA > UBound(mData, 1) Then
mMessage = "指定的因子 A(试点)的 Index 越界,即现有的样本数据集没有所指
定的数据!"
Anova1Calc = caiCancel
Exit Function
End If
InitResults
' Calclating SSs and dFs
iT = CalcSSdFs1(idxA)
If iT <> caiOK Then
InitResults
mAnovaResultState = IIf(iT = caiCancel, 0, caiError)
Anova1Calc = iT
Exit Function
End If
mAnovaResultState = 11
mIdxA = idxA
' Calclating F Values
CalcAnova1Fs
mAnovaResultState = 12
Anova1Calc = caiOK
End Function
' 双因子有重复样本的方差分析计算
' iMode: 1 -- 关于因子 A 的处理是随机的,0 -- 是固定的
Private Function Anova2Calc() As Integer
Dim iT As Integer
If mDataState <= 0 Then
mMessage = "没收到有效的原始样本数据,无法进行单因子方差分析!"
mAnovaResultState = 0
Anova2Calc = caiCancel
Exit Function
End If
' Calclating SSs and dFs
iT = CalcSSdFs2()
If iT <> caiOK Then
InitResults
mAnovaResultState = IIf(iT = caiCancel, 0, caiError)
Anova2Calc = iT
Exit Function
End If
mAnovaResultState = 21
mIdxA = 0
' Calclating F Values
CalcAnova2Fs
mAnovaResultState = 22
Anova2Calc = caiOK
End Function
' Multiple Comparison Test according to Duncan's Multiple-Range Method.
'
dMean(): sorted means for each group, i.e. dMean(i) >= dMean(j), if i>j;
'
iSize: the number of groups which's mean to be compared;
'
dDev: = sqrt(MSx/n), n is the size of each group; MSx may be MSerr or MSab according to
design mode: Fixed or Radomized
'
idF: the degree of freedom of the dDev
Private Function MultiCompSSR(dMean() As Double, iSize As Integer, dDev As Double, idF As
Integer) As Integer
Dim I As Integer, iT As Integer, iSz As Integer
Dim dSSR() As Double
Dim cReport() As Integer
Dim strT As String
On Error GoTo MCompSSRFail
iSz = IIf(iSize < 20, iSize, 20)
ReDim dSSR(iSz - 1), cReport(iSz * 20)
For I = 1 To iSz * 20
cReport(I) = Asc(" ")
Next I
' with 0.01 Significance
If DuncanSSR(dSSR(), iSz, idF, 0.01) = caiError Then GoTo MCError
If MultiCompReport(dMean(), iSz, cReport(), 10, dDev, cMcSSR, dSSR()) = caiError Then GoTo
MCError
'
cReport = UCase(cReport) '???!
For I = 1 To iSz * 20
strT = Chr(cReport(I))
strT = UCase(strT)
cReport(I) = Asc(strT)
Next I
' with 0.05Significance
If DuncanSSR(dSSR(), iSz, idF, 0.05) = caiError Then GoTo MCError
If MultiCompReport(dMean(), iSz, cReport(), 0, dDev, cMcSSR, dSSR()) = caiError Then GoTo
MCError
' Store the report
ReDim mMCompReport(iSz)
For I = 1 To iSz
With mMCompReport(I)
.Mean = dMean(I)
.Classif = ""
For iT = 1 To 20
.Classif = .Classif & Chr(cReport((I - 1) * 20 + iT))
Next iT
End With
Next I
MultiCompSSR = caiOK
Exit Function
MCError:
mMessage = modMessage
MultiCompSSR = caiError
Exit Function
MCompSSRFail:
mMessage = "实施多重比较 SSR 时出错!错误号:" & Err.Number & vbCrLf _
& "说明:" & Err.Description
MultiCompSSR = caiError
End Function
' Multiple Comparison Test according to LSD Method.
'
dMean(): sorted means for each group, i.e. dMean(i) >= dMean(j), if i>j;
'
iSize: the number of groups which's mean to be compared;
'
dDev: is the Comparision Constant "S=sqr(2*MSx/n), here MSx may be MSerr or MSab
according to the design mode of the Test: Fixed or Radomized
'
idF: the degree of freedom of the dMSe
Private Function MultiCompLSD(dMean() As Double, iSize As Integer, dDev As Double, idF As
Integer) As Integer
Dim I As Integer, iT As Integer, iSz As Integer
Dim cReport() As Integer
Dim dLSD As Double
Dim strT As String
On Error GoTo MCompLSDFail
iSz = IIf(iSize < 20, iSize, 20)
ReDim cReport(iSz * 20)
For I = 1 To iSz * 20
cReport(I) = Asc(" ")
Next I
' with 0.01 Significance
dLSD = TTest(idF, 0.01)
dLSD = dDev * dLSD
If MultiCompReport(dMean(), iSz, cReport(), 10, dLSD, cMcLSD) = caiError Then GoTo
MCLSDError
For I = 1 To iSz * 20
strT = Chr(cReport(I))
strT = UCase(strT)
cReport(I) = Asc(strT)
Next I
' with 0.05Significance
dLSD = TTest(idF, 0.05)
dLSD = dDev * dLSD
If MultiCompReport(dMean(), iSz, cReport(), 0, dLSD, cMcLSD) = caiError Then GoTo
MCLSDError
' Store the report
ReDim mMCompReport(iSz)
For I = 1 To iSz
With mMCompReport(I)
.Mean = dMean(I)
.Classif = ""
For iT = 1 To 20
.Classif = .Classif & Chr(cReport((I - 1) * 20 + iT))
Next iT
End With
Next I
MultiCompLSD = caiOK
Exit Function
MCLSDError:
mMessage = modMessage
MultiCompLSD = caiError
Exit Function
MCompLSDFail:
mMessage = "实施多重比较 LSD 时出错!错误号:" & Err.Number & vbCrLf _
& "说明:" & Err.Description
MultiCompLSD = caiError
End Function
' Doing Equality Test according to Cochran:
' Input Parameters: MSes() -- Array of Variances sorted ascendly;
'
iSize -- Number of Variances to be tested; idF -- the Degree of Freedom for each
Variance
' Note: Here we assume that all Mses have the same value of the Degree of Freedom!!!
' Test result is stored to mEqTestREsult
' Return values: CaiOK -- Equality Accepted, i.e. Gmax <= Gtab005; 1 -- Equality Rejected on
0.05 Sig.; 2 -- REeected on 0.01Sig.;
'
CaiCancel -- Test failed, mostly due to wrong value of input parameters, e.g. iSize > 40
Private Function EqualityCochran(MSes() As Double, iSize As Integer, idF As Integer) As Integer
Dim dSum As Double, Gmax As Double, Gtab001 As Double, Gtab005 As Double
Dim I As Integer
Gtab005 = CochranTab(iSize, idF, 0.05)
If Gtab005 < 0 Then GoTo EqCochFail
Gtab001 = CochranTab(iSize, idF, 0.01)
If Gtab001 < 0 Then GoTo EqCochFail
dSum = 0
For I = 1 To iSize
dSum = dSum + MSes(I)
Next
Gmax = MSes(iSize) / dSum
With mEqTestResult
.MethodName = "Cochran"
.Size = iSize
.dF = idF
.EvalValue = Gmax
.CritVal001 = Gtab001
.CritVal005 = Gtab005
If Gmax > Gtab001 Then
.Result = 2
ElseIf Gmax > Gtab005 Then
.Result = 1
Else
.Result = 0 ' caiOK
End If
EqualityCochran = .Result
End With
Exit Function
EqCochFail:
mEqTestResult.Result = caiCancel
EqualityCochran = caiCancel
mMessage = modMessage
End Function
' Doing Equality Test according to Bartlette:
' Input Parameters: MSes() -- Array of Variances sorted ascendly;
'
iSize -- Number of Variances to be tested; idF -- the Degree of Freedom for each
Variance;
' Note:In General, idF should be 4 or more, and iSize should great than 10,
'
otherwise this method for Equality Test should not be used.
'
However, the restrictions doesn't implemented here, it depends on the Caller to take
care of them
' Test result is stored to mEqTestREsult
' Return values: CaiOK -- Equality Accepted, i.e. XsquV <= XSquT005; 1 -- Equality Rejected on
0.05 Sig.; 2 -- REeected on 0.01Sig.;
'
CaiCancel -- Test failed, mostly due to wrong value of input parameters, e.g. iSize > 30,
or dAlpha is other than 0.01 or 0.05
Private Function EqualityBartlette(MSes() As Double, iSize As Integer, idF As Integer) As Integer
Dim XsquV As Double, XSquT005 As Double, XSquT001 As Double, dSum As Double,
dSumLog As Double
Dim I As Integer
XSquT005 = XSquareTab(iSize - 1, 0.05)
If XSquT005 < 0 Then GoTo EqBartFail
XSquT001 = XSquareTab(iSize - 1, 0.01)
If XSquT001 < 0 Then GoTo EqBartFail
dSum = 0: dSumLog = 0
For I = 1 To iSize
dSum = dSum + MSes(I)
dSumLog = dSumLog + Log(MSes(I)) / Log(10#)
Next
XsquV = 2.3026 * iSize * idF * (Log(dSum / iSize) / Log(10#) - dSumLog / iSize)
XsquV = XsquV / ((iSize + 1) / (3 * iSize * idF) + 1)
With mEqTestResult
.MethodName = "Bartlette"
.Size = iSize
.dF = idF
.EvalValue = XsquV
.CritVal001 = XSquT001
.CritVal005 = XSquT005
If XsquV > XSquT001 Then
.Result = 2
ElseIf XsquV > XSquT005 Then
.Result = 1
Else
.Result = 0 ' caiOK
End If
EqualityBartlette = .Result
End With
Exit Function
EqBartFail:
EqualityBartlette = caiCancel
mMessage = modMessage
mEqTestResult.Result = caiCancel
End Function
' Calclating Variances from mData() indicated by iIdx for Equality Test
' iIdx: >0 -- Sample Data Set = mData(iidxa, *, *); 0 -- Sampl Data Set = mData(*, *, *)
' The Variances calclated are stored into mVRData()
Private Function CalcVariances(iIdxA As Integer) As Integer
Dim n1 As Integer, n2 As Integer, n3 As Integer
Dim I As Integer, J As Integer, k As Integer, dTemp As Double
On Error GoTo CalaVarsFail
If Abs(mDataState) < 3 Or (mDataState = -3 And iIdxA > 1) Then
mMessage = "没发现指定的方差分析原始样本数据,无法进行同质性检验!"
mVRDataState = 0
CalcVariances = caiCancel
Exit Function
End If
n1 = UBound(mData, 1)
n2 = UBound(mData, 2)
n3 = UBound(mData, 3)
Select Case iIdxA
Case 1 To n1 ' With Anova1 Analysis, i.e. one Site
If mAnovaResultState < 11 Or mIdxA <> iIdxA Then
InitResults
I = CalcSSdFs1(iIdxA)
If I <> caiOK Then
InitResults
mAnovaResultState = IIf(I = caiCancel, 0, caiError)
mVRDataState = 0
CalcVariances = I
Exit Function
End If
mAnovaResultState = 11
mIdxA = iIdxA
End If
ReDim mVRData(n2)
For I = 1 To n2
dTemp = 0
For J = 1 To n3
dTemp = dTemp + mData(mIdxA, I, J) * mData(mIdxA, I, J)
Next J
mVRData(I) = (dTemp - T2(I) * T2(I) / n3) / (n3 - 1)
Next I
With mEqTestResult
.Size = n2
.dF = n3 - 1
End With
Case 0 ' With Anova2 Analysis, i.e. Multi Sites
If mAnovaResultState < 21 Then
I = CalcSSdFs2()
If I <> caiOK Then
InitResults
mAnovaResultState = IIf(I = caiCancel, 0, caiError)
mVRDataState = 0
CalcVariances = I
Exit Function
End If
mAnovaResultState = 21
mIdxA = 0
End If
ReDim mVRData(n1)
Dim dT2 As Double, dT3 As Double, dCF As Double
For I = 1 To n1
dCF = T1(I) * T1(I) / (n2 * n3)
dTemp = 0
dT2 = 0
dT3 = 0
For J = 1 To n2
For k = 1 To n3
dTemp = dTemp + mData(I, J, k) * mData(I, J, k)
Next k
dT2 = dT2 + X21(J, I) * X21(J, I)
Next J
For k = 1 To n3
dT3 = dT3 + T31((I - 1) * n3 + k) * T31((I - 1) * n3 + k)
Next k
dTemp = dTemp - dCF
' SST for the Site I
dT2 = dT2 / n3 - dCF
' SSb for the Site
dT3 = dT3 / n2 - dCF
' SSr for the Site
mVRData(I) = (dTemp - dT2 - dT3) / ((n2 - 1) * (n3 - 1))
SSerr/dFerr
Next I
With mEqTestResult
.Size = n1
.dF = (n2 - 1) * (n3 - 1)
End With
' MSerr =
Case Else
mMessage = "指定的因子 A(试点)的 Index 越界,即现有的样本数据集没有
所指定的数据!"
mVRDataState = 0
CalcVariances = caiCancel
Exit Function
End Select
mVRDataState = 1
CalcVariances = caiOK
Exit Function
CalaVarsFail:
mMessage = "计算方差时出错!错误号:" & Err.Number & vbCrLf _
& "说明:" & Err.Description
mEqTestResult.Result = caiError
mVRDataState = 0
CalcVariances = caiError
End Function
' 同质性检验控制程序:此时 mVRData()存放着各参试组的方差值,其自由度及参试组个数
等存放在 mEqTestResult
' iMethod -- 检验方法:0 -- 常规(参试组个数<10 时用 Cochran 法,否则用 Bartellet)
; 1 -Cochran; 2 -- Bartlette
' Return Values: <0 -- 同质性检验失败: -1, caiCancel -- 参数不合要求;-2, caiError -- 检验中
出错
'
>=0 -- 同质性检验顺利完成: 0, caiOK -- 接受同质性; 1 -- 拒绝同质性(显著性
0.05); 2 -- 拒绝同质性(显著性 0.01)
Private Function EqualityTest(iMethod As Integer) As Integer
Dim dStVars() As Double, iSortedIdx() As Integer
Dim I As Integer, iSize As Integer, idF As Integer
On Error GoTo EquTestFail
' Sort the Variances
With mEqTestResult
iSize = .Size
idF = .dF
End With
ReDim dStVars(iSize), iSortedIdx(iSize)
SortArray mVRData(), iSize, iSortedIdx(), True
For I = 1 To iSize
dStVars(I) = mVRData(iSortedIdx(I))
Next I
'ordered Acsendly
Select Case iMethod
Case cDefault
' 0, Nomal
If iSize < 10 Then
EqualityTest = EqualityCochran(dStVars(), iSize, idF)
ElseIf iSize >= 10 And idF >= 4 Then
EqualityTest = EqualityBartlette(dStVars(), iSize, idF)
Else
mMessage = "按一般规则,同质性检验当参试组个数小于 10 时采用
Cochran 法," _
& "10 个以上时采用 Bartlette 法,但后者要求参试的每个方差的
自由度应大于 3。" _
& "您选择的样本数据不符合上述要求。" & vbCrLf & vbCrLf _
& "若您坚持要求进行同质性检验,请自已确定用何种方法。"
mEqTestResult.Result = caiCancel ' -1
EqualityTest = caiCancel
End If
Case cEqCoch
' 1, Cochraan
EqualityTest = EqualityCochran(dStVars(), iSize, idF)
Case cEqBart
' 2, Bartlette
EqualityTest = EqualityBartlette(dStVars(), iSize, idF)
Case Else
mMessage = "同质性检验方法当前仅支持:0 -- 常规;1 -- Cochran;2 -Bartlette!"
mEqTestResult.Result = caiCancel
EqualityTest = caiCancel
Exit Function
End Select
Exit Function
EquTestFail:
mMessage = "实施同质性检验时出错!错误号:" & Err.Number & vbCrLf _
& "说明:" & Err.Description
mEqTestResult.Result = caiError
EqualityTest = caiError
End Function
' Calclating Sample Data (Xi, Yi) for Regression Analysis from mData() that has contained the
Sample Data for
' Anova2 (Multi Sites) Analysis. "iIndexB" indecates the level of Factor B (the Variety) to be
concerned.
' Xi is the Average Value of all levels of Factor B in the ith treatment of Factor A (the Average Yield
per plot of all
' Varieties in the ith Site), and will be stored to mVRData(1, i); Yi is the Average Value of the
iIndexBth level of
' Factor B in the ith level of Factor A (the Average Yield per plot of the iIndexBth. Variety in the
ith. Site), and
' will be stored to mVRData(2, i).
Private Function RegresSDataPrepare(iIndexB)
Dim n1 As Integer, n2 As Integer, n3 As Integer
Dim I As Integer, J As Integer, k As Integer
On Error GoTo RegDataFail
' Check if the Sample Data for Anova2 is Avialable
If mDataState < 3 Then
mMessage = "没发现用于 Anova2 的原始样本数据,无法进行相关性检验!"
GoTo RegDataCancel
End If
n1 = UBound(mData, 1)
n2 = UBound(mData, 2)
n3 = UBound(mData, 3)
If iIndexB > n2 Or iIndexB < 1 Then
mMessage = "因子 B 仅有" & Str(n2) & "种不同处理水平,指定的序号无效!"
GoTo RegDataCancel
End If
' Check, if SSxs calclating has been done already
If mAnovaResultState < 21 Then
I = CalcSSdFs2()
If I <> caiOK Then
InitResults
mAnovaResultState = IIf(I = caiCancel, 0, caiError)
GoTo RegDataCancel
End If
mAnovaResultState = 21
mIdxA = 0
End If
' Calclating (Xi, Yi)
ReDim mVRData(2, n1)
J = n2 * n3
For I = 1 To n1
mVRData(1, I) = T1(I) / J
mVRData(2, I) = X21(iIndexB, I) / n3
Next I
mVRDataState = 2
RegresSDataPrepare = caiOK
Exit Function
RegDataCancel:
mVRDataState = 0
RegresSDataPrepare = caiCancel
Exit Function
RegDataFail:
mMessage = "从 Anova2 样本数据计算回归分析所需样本数据时出错!错误号:" &
Err.Number & vbCrLf _
& "说明:" & Err.Description
mVRDataState = 0
RegresSDataPrepare = caiError
End Function
' Regression Analysis, SampleData of pare of (Xi, Yi)s have been stored in mVRData(),
' and the result will be stored in mRegresResult
Private Function RegressionAnaly() As Integer
Dim I As Integer, iSize As Integer
Dim Tx As Double, Ty As Double
Dim SSxx As Double, SSyy As Double, SSxy As Double
Dim Ra001 As Double, Ra005 As Double
On Error GoTo RegCalcFail
iSize = UBound(mVRData, 2)
If iSize < 4 Then
mMessage = "所提供的样本数小于 4,不宜进行回归分析!"
RegressionAnaly = caiCancel
End If
' Regression Calclating
Tx = 0: Ty = 0: SSxx = 0: SSyy = 0: SSxy = 0
For I = 1 To iSize
Tx = Tx + mVRData(1, I)
Ty = Ty + mVRData(2, I)
SSxx = SSxx + mVRData(1, I) * mVRData(1, I)
SSyy = SSyy + mVRData(2, I) * mVRData(2, I)
SSxy = SSxy + mVRData(1, I) * mVRData(2, I)
Next
SSxx = SSxx - Tx * Tx / iSize
SSyy = SSyy - Ty * Ty / iSize
SSxy = SSxy - Tx * Ty / iSize
With mRegresResult
.Slope = SSxy / SSxx
.Intercept = (Ty - .Slope * Tx) / iSize
.CorCorf = SSxy / Sqr(SSxx * SSyy)
.Size = iSize
End With
' Correlative Test
Ra001 = RaTab(iSize - 2, 0.01)
Ra005 = RaTab(iSize - 2, 0.05)
If Ra001 < 0 Or Ra005 < 0 Then
mRegresResult.Result = caiCancel
RegressionAnaly = caiCancel
' means that Data about slope, Interception and Correlative Coefficient is Valid
Exit Function
End If
With mRegresResult
.CritRa001 = Ra001
.CritRa005 = Ra005
If .CorCorf < .CritRa005 Then
.Result = 0
ElseIf .CorCorf >= .CritRa001 Then
.Result = 2
Else
.Result = 1
End If
End With
RegressionAnaly = caiOK
Exit Function
RegCalcFail:
mMessage = "计算回归方程时出错!错误号:" & Err.Number & vbCrLf _
& "说明:" & Err.Description
mRegresResult.Result = caiError
RegressionAnaly = caiError
End Function
' ***********************************************************************
' Public Methods (i.e. the Interface of the class
' ***********************************************************************
' 设定原始样本数据,对它可进行方差分析、多重比较、及其它相关的统计检验。
' sData() 包含原始样本数据,
应是满足右列格式的三维数组:sData(因子 A Index, 因子 B Index,
重复 Index),
' 或是满足右列格式的二维数组:sData(因子 Index, 重复 Index)。iDim -- 数组的维数
' 注:当 sData()为二维时会产生付作用:mData()被这里的 sData()复盖,维数变为(1, n2, n3),
因而不能再为
'
其它方差分析共享,即 Anova1WOD(), Anova2WOD()均不能利用 mData()了,需要重新
设定样本数据后才能调用。
Public Function SetSampleData(ByRef sData() As Single, iDim As Integer) As Integer
Dim iT As Integer
iT = CheckAnovaSourceData(sData, iDim)
If iT = caiError Then
mMessage = mMessage & " 不能接受该样本数据!"
mAnovaResultState = 0
SetSampleData = caiError
Exit Function
End If
SetSampleData = caiOK
End Function
' 单因子有重复样本的方差分析(完全随机区组设计):
' sData() 包含原始样本数据,应是满足右列格式的二维数组:sData(因子 Index, 重复 Index)
' 此函数产生付作用:mData()被这里的 sData()复盖,维数变为(1, n2, n3),因而不能再为其
它方差分析共享
'
即 Anova1WOD(), Anova2WOD()均不能利用 mData()了,需要重新设定样本数据后才能
调用。
Public Function Anova1WSD(ByRef sData() As Single) As Integer
Dim iT As Integer
iT = CheckAnovaSourceData(sData, 2)
If iT < 0 Then
mMessage = mMessage & " 无法完成单因子方差分析!"
mAnovaResultState = IIf(iT = caiCancel, 0, caiError)
Anova1WSD = iT
Exit Function
End If
Anova1WSD = Anova1Calc(1)
mDataState = -3
End Function
' 同 Anova1WSD, 只是使用已存入 mData()的样本数据,Index 指明样本数据位于 mData(Index,
*, *)
Public Function Anova1WOD(ByVal Index As Integer) As Integer
Anova1WOD = Anova1Calc(Index)
End Function
' 用于区试(一年多点), 即多个"完全随机区组设计试验"的联合方差分析
' sData() 包含原始样本数据,
应是满足右列格式的三维数组:sData(因子 A Index, 因子 B Index,
重复 Index)
' iMode: 1 -- 关于因子 A 的处理是随机的,0 -- 是固定的
Public Function Anova2WSD(ByRef sData() As Single, ByVal iMode As Integer) As Integer
Dim iT As Integer
iT = CheckAnovaSourceData(sData, 3)
If iT < 0 Then
mMessage = mMessage & " 无法完成联合方差分析!"
mAnovaResultState = IIf(iT = caiCancel, 0, caiError)
Anova2WSD = iT
Exit Function
End If
mAnova2Mode = IIf(iMode, 2, 1)
Anova2WSD = Anova2Calc()
End Function
' 同 Anova2WSD, 只是使用已存入 mData()的样本数据
Public Function Anova2WOD(ByVal iMode As Integer) As Integer
mAnova2Mode = IIf(iMode, 2, 1)
Anova2WOD = Anova2Calc()
End Function
' 用于双因子随机区组试验方差分析(关于区组间的变异, 对因子 A 的不同处理水平同等对
待)
' sData() 包含原始样本数据,
应是满足右列格式的三维数组:sData(因子 A Index, 因子 B Index,
重复 Index)
' iMode: 1 -- 因子 A, B 都固定; 2 -- A 固定, B 随机; 3 -- A 随机, B 固定; 4 -- A,B 都随
机.
Public Function Anova2gWSD(ByRef sData() As Single, ByVal iMode As Integer) As Integer
Dim iT As Integer
iT = CheckAnovaSourceData(sData, 3)
If iT < 0 Then
mMessage = mMessage & " 无法完成双因子随机区组试验方差分析!"
mAnovaResultState = IIf(iT = caiCancel, 0, caiError)
Anova2gWSD = iT
Exit Function
End If
mAnova2Mode = iMode + 10
Anova2gWSD = Anova2Calc()
End Function
' 同 Anova2gWSD, 只是使用已存入 mData()的样本数据
Public Function Anova2gWOD(ByVal iMode As Integer) As Integer
mAnova2Mode = iMode + 10
Anova2gWOD = Anova2Calc()
End Function
' 在方差分析的基础上对 mData()中的原始数据关于因子 B(作物品种)作多重比较。比较
的
'
结果报告将存放在类型为 MCREport 的数组 mMCompReport()中,该数组的每一项对
应于一个组,
'
并按均值的降幂排列,其中".Index"为该组在原始数据中对应于因子 B 的 Index(序
号)
。
' iMethod:指定多重比较方法 = cMcLSD or cMcSSR,即 1 或 2
' iMode:指定关于因子 A 的设计模型,=cFixed or cRadomized,即 0 或 1
Public Function MultiCompareAnova(ByVal iMethod As Integer, ByVal iMode As Integer) As
Integer
Dim dMeans() As Double, dStMeans() As Double, iSortedIdx() As Integer
Dim dMSx As Double, idFx As Integer
Dim I As Integer, iSize As Integer, n3 As Integer
On Error GoTo MCAnovaFail
' Set the Mean Value for each Group (the Treatment of Factor B), e.g. for each Variety
If Abs(mDataState) < 3 Then
mMessage = "没有用于方差分析的原始数据,无法进行多重比较!"
MultiCompareAnova = caiCancel
Exit Function
End If
iSize = UBound(mData, 2)
n3 = UBound(mData, 3)
ReDim dMeans(iSize), dStMeans(iSize), iSortedIdx(iSize)
Select Case mAnovaResultState
Case 11 To 19
' Under Anova1 Analysis, i.e. one Site
For I = 1 To iSize
dMeans(I) = T2(I) / n3
Next I
With mAnovaResult
dMSx = .SSerr / .dFerr
If iMethod = cMcSSR Then
dMSx = Sqr(dMSx / n3)
ElseIf iMethod = cMcLSD Then
dMSx = Sqr(2 * dMSx / n3)
End If
idFx = .dFerr
End With
Case 21 To 29
' Under Anova2 Analysis, i.e. Multi Sites
For I = 1 To iSize
dMeans(I) = T2(I) / ((mAnovaResult.dFa + 1) * n3)
Next I
With mAnovaResult
If .SSab = 0 And iMode = cRadomized Then
mMessage = "计算发现来自因子 A、B 间互作的变异的平方
和为 0!" _
& "要对该样本数据作多重比较,只能采用固定模式。 "
MultiCompareAnova = caiCancel
Exit Function
End If
dMSx = IIf(iMode = cFixed, .SSerr / .dFerr, .SSab / .dFab)
If iMethod = cMcSSR Then
dMSx = Sqr(dMSx / ((.dFa + 1) * n3))
ElseIf iMethod = cMcLSD Then
dMSx = Sqr(2 * dMSx / ((.dFa + 1) * n3))
End If
idFx = IIf(iMode = cFixed, .dFerr, .dFab)
End With
Case Else
mMessage = "本函数仅在方差分析后实施多重比较,请先进行方差分析或调用
其它函数实施多重比较。"
MultiCompareAnova = caiCancel
Exit Function
End Select
' Sorting dMeans()
SortArray dMeans(), iSize, iSortedIdx(), False
If iSize > 20 Then iSize = 20
ReDim mMCompReport(iSize)
For I = 1 To iSize
dStMeans(I) = dMeans(iSortedIdx(I))
Next I
'ordered Decsendly
' Multiple Comparision
Select Case iMethod
Case cMcLSD
I = MultiCompLSD(dStMeans(), iSize, dMSx, idFx)
Case cMcSSR
I = MultiCompSSR(dStMeans(), iSize, dMSx, idFx)
Case Else
mMessage = "本函数仅支持两种多重比较方法:1 -- LSD;2 -- SSR Duncan"
MultiCompareAnova = caiCancel
End Select
If I <> caiOK Then
MultiCompareAnova = I
Exit Function
End If
For I = 1 To iSize
mMCompReport(I).Index = iSortedIdx(I)
Next I
MultiCompareAnova = caiOK
Exit Function
MCAnovaFail:
mMessage = "实施 Anova 多重比较时出错!错误号:" & Err.Number & vbCrLf _
& "说明:" & Err.Description
MultiCompareAnova = caiError
End Function
' 根据提供的平均值 dMeans(),及对应的 dMSx 及其自由度(idF)、平均值的样本容量(iGn)作多
重比较。比较的
'
结果报告将存放在类型为 MCREport 的数组 mMCompReport()中,该数组的每一项对
应于一个组,
'
并按均值的降幂排列,其中".Index"为该组在原始数据中的顺序号。
' iMethod:指定多重比较方法 = cMcLSD or cMcSSR,即 1 或 2
' 注意:dMSx 应取合适的均方差,如在固定模式下取 MSerr,在随机模式取 MSab。
Public Function MultiCompareWSD(ByRef dMeans() As Double, ByVal dMSx As Double, ByVal idFx
As Integer, _
ByVal iGn As Integer, ByVal iMethod As Integer) As Integer
Dim dTMeans() As Double, dStMeans() As Double, iSortedIdx() As Integer
Dim I As Integer, iSize As Integer, iB As Integer
On Error GoTo MCWsdFail
' It's not sure that dMeans() will based on 1 to n subscripting, so, transforming is neccessary
iB = LBound(dMeans)
iSize = UBound(dMeans) - iB + 1
ReDim dTMeans(iSize), dStMeans(iSize), iSortedIdx(iSize)
For I = 1 To iSize
dTMeans(I) = dMeans(iB - 1 + I)
Next I
' Sorting dMeans()
SortArray dTMeans(), iSize, iSortedIdx(), False
'ordered Decsendly
If iSize > 20 Then iSize = 20
ReDim mMCompReport(iSize)
For I = 1 To iSize
dStMeans(I) = dMeans(iSortedIdx(I))
Next I
' Multiple Comparision
Select Case iMethod
Case cMcLSD
dMSx = Sqr(2 * dMSx / iGn)
I = MultiCompLSD(dStMeans(), iSize, dMSx, idFx)
Case cMcSSR
dMSx = Sqr(dMSx / iGn)
I = MultiCompSSR(dStMeans(), iSize, dMSx, idFx)
Case Else
mMessage = "本函数仅支持两种多重比较方法:1 -- LSD;2 -- SSR Duncan"
MultiCompareWSD = caiCancel
Exit Function
End Select
If I <> caiOK Then
MultiCompareWSD = I
Exit Function
End If
For I = 1 To iSize
mMCompReport(I).Index = iSortedIdx(I)
Next I
MultiCompareWSD = caiOK
Exit Function
MCWsdFail:
mMessage = "实施 Anova 多重比较时出错!错误号:" & Err.Number & vbCrLf _
& "说明:" & Err.Description
MultiCompareWSD = caiError
End Function
' 利用当前的 Anova 样本数据对各组数据的样本方差的同质性进行检验
' iIdxA,用于指明样本数据:
'
>0 -- mData(iIdxA, *, *),即指 Anova1(单点)数据,因子 B 的每一个处理(品种)
的样本数据构成一个组;
'
=0 -- mData(*,*,*),即 Anova2(多点)数据,与因子 A 每一个处理(试点)相关的所
有样本数据
'
(包括因子 B 的各种处理)构成一个组,其方差值取该处理(试点)的
MSerr,即 Experimental Error.
' iMethod -- 检验方法:0 -- 常规(参试组个数<10 时用 Cochran 法,否则用 Bartellet)
; 1 -Cochran; 2 -- Bartlette
' Return Values: <0 -- 同质性检验失败: -1, caiCancel -- 参数不合要求;-2, caiError -- 检验中
出错
'
>=0 -- 同质性检验顺利完成: 0, caiOK -- 接受同质性; 1 -- 拒绝同质性(显著性
0.05); 2 -- 拒绝同质性(显著性 0.01)
' 当检验顺利完成时,mVRData()存放着参试的方差值(按原有的顺序),
'
mEqTestResult 存放着检验结果及相关信息。调用者可通过相应的 Get Property 访问
它们。
Public Function EqualityAnova(ByVal iIdxA As Integer, ByVal iMethod As Integer) As Integer
Dim I As Integer
' Calclate the Variances
I = CalcVariances(iIdxA)
If I <> caiOK Then
EqualityAnova = I
Exit Function
End If
EqualityAnova = EqualityTest(iMethod)
End Function
' 同质性检验:dVars()存放着各参试组的方差值(按原有顺序,不必排序,亦不计其 Index
的起始值)
,idF 为其自由度
' iMethod -- 检验方法:0 -- 常规(参试组个数<10 时用 Cochran 法,否则用 Bartellet)
; 1 -Cochran; 2 -- Bartlette
' Return Values: <0 -- 同质性检验失败: -1, caiCancel -- 参数不合要求;-2, caiError -- 检验中
出错
'
>=0 -- 同质性检验顺利完成: 0, caiOK -- 接受同质性; 1 -- 拒绝同质性(显著性
0.05); 2 -- 拒绝同质性(显著性 0.01)
' 当检验顺利完成时,mVRData()存放着参试的方差值(按原有的顺序),
'
mEqTestResult 存放着检验结果及相关信息。调用者可通过相应的 Get Property 访问
它们。
Public Function EqualityWSD(ByRef dVars() As Double, ByVal idF As Integer, ByVal iMethod As
Integer) As Integer
Dim I As Integer, iB As Integer, iSize As Integer
On Error GoTo EqWSDFail
iB = LBound(dVars)
iSize = UBound(dVars) - iB + 1
ReDim mVRData(iSize)
For I = 0 To iSize - 1
If dVars(iB + I) >= 0 Then
mVRData(I + 1) = dVars(iB + I)
Else
GoTo EqWSDFail
End If
Next I
With mEqTestResult
.Size = iSize
.dF = idF
End With
mVRDataState = 1
EqualityWSD = EqualityTest(iMethod)
Exit Function
EqWSDFail:
mMessage = "提供的含有方差值的数组出错(如方差值为负数、非一维数组等)!错误
号:" _
& Err.Number & vbCrLf & "说明:" & Err.Description
mEqTestResult.Result = caiError
mVRDataState = 0
EqualityWSD = caiError
End Function
' 在 Anova2 分析中,对指定的因子 B 的一个处理水平(如一个品种)与它的所有处理水平
在每一个
' 因子 A 的处理水平(试验地点)下的平均值之间作回归分析。前者作为 Y, 后者作为 X。
' 参数 iIndexB 即为此指定的 B 的处理水平的序号(属于闭区间[1, n2],n2 为因子 B 的处理
个数)
' 即回归样本数据为:(Xi, Yi), i=1, 2, ... n1,其中 n1 为因子 A 的处理个数;Xi -- 在因子 A 的
第 i 个处理水平
' 下关于因子 B 的所有处理的平均值(第 i 个试点中所有品种的平均产量);Yi -- 在因子 A
的第 i 个处理
' 水平下关于因子 B 的第 iIndexB 个处理的平均值(第 i 个试点中第 iIndexB 个品种的平均
产量)
' 分析结果可访问 Property ctRegresREsult 获得,Xi -- Property dXYSamples(1, i),Yi -dXYSamples(2, i)。
' 注:样本数据(X,Y)按因子 A 的处理水平的序号排列,并未按 Xi 值的大小排序
Public Function RegressionAnova(ByVal iIndexB As Integer) As Integer
Dim I As Integer
' Prepare Sample Data for Regression Analysis
I = RegresSDataPrepare(iIndexB)
If I <> caiOK Then
RegressionAnova = I
Exit Function
End If
RegressionAnova = RegressionAnaly()
End Function
' 按提供的样本数据进行回归分析:iSize 为样本个数,第 i 个样本为(X(i), Y(i))
' 分析结果可访问 Property ctRegresREsult 获得
'
Public Function RegressionWSD(ByRef X() As Double, ByRef Y() As Double, ByVal iSize As Integer)
As Integer
Dim I As Integer, iB As Integer
On Error GoTo RegWSDFail
' Prepare Sample Data for Regression Analysis
iB = LBound(X)
ReDim mVRData(2, iSize)
For I = 1 To iSize
mVRData(1, I) = X(iB - 1 + I)
mVRData(2, I) = Y(iB - 1 + I)
Next I
RegressionWSD = RegressionAnaly()
Exit Function
RegWSDFail:
mMessage = "所提供的用于回归分析的样本数据有问题,如样本个数与 X(), Y()的容量不
符!"
RegressionWSD = caiError
End Function
Download