我正在调试一个VBA宏,它以以下错误消息结束:
“运行时错误'1004':
找不到。检查文件名的拼写,然后验证 文件位置正确。
如果您尝试从最近使用过的文件列表中打开该文件,请确保该文件尚未重新命名,移动或删除。“
我检查过我没有使用已删除/已删除/重命名的文件,但这些文件并非来自我的“近期文件”列表。
触发错误消息的代码的违规部分:
Workbooks.OpenText Filename:=vCPath _
, Origin:=437, StartRow:=1, DataType:=xlDelimited, TextQualifier:= _
xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=False, Semicolon:=False _
, Comma:=True, Space:=False, Other:=False, FieldInfo:=Array(Array(1, 1), _
Array(2, 1), Array(3, 1), Array(4, 1), Array(5, 1), Array(6, 1), Array(7, 1), Array(8, 1), _
Array(9, 1), Array(10, 1), Array(11, 1), Array(12, 1), Array(13, 1)), _
TrailingMinusNumbers:=True
以下是所有代码:
' Changes to program to make
' Exclude outliers in average
' Develop fake data to at glance recognize whether program works.
' Source http://www.cpearson.com/excel/optimize.htm
' Declare .Filters
Option Explicit
Sub DataProcessingExperiment7()
On Error GoTo ErrorHandler
' Declare as strings, as integers, as variants, decDecimals, as Office.FileDialog
Dim strPath, strFileN, strDirN, strRangeNOut, strRangeNIn, strFilename, strTLCorn, strBRCorn, strSelectedFile, strtemp_name As String
Dim vResMatrix(), vCPath, vFileN As Variant
Dim vRangeNOut, vRangeNIn, decInd6, decInd4, decInd5, decStep2, decMRow, decColIn, decInd3, decMcol As Double
Dim decMxRNo, decBgrSum, decRowIn, decInd, decM40eff, decStep, decColNo, decStartcol, decStartrow As Double
Dim decPlateNo, decMonoVal, decInd1, decEntryRow2, decEntryRow, decInd2, decBgrValP, decBgrRow As Double
Dim decBrgSum, decBgrVal, decRangeNIn, decRangeNOut, decTLCorn, decVolcorr, decBRCorn, decMEeff As Double
Dim decMediaVal, M40Eff, decMeanComp As Double
' MEeff = measure of efflux due to crudely purified HDL in scintillation
' Math operations are fastest with Integers / UIntegers: https://msdn.microsoft.com/en-us/library/ae55hdtk.aspx
' Start File Explorer to select file containing data
Dim lngCount As Long
' Open the file dialog
With Application.FileDialog(msoFileDialogOpen)
.AllowMultiSelect = True
.Show
' Display paths of each file selected
For lngCount = 1 To .SelectedItems.Count
Next lngCount
For Each strFilename In .SelectedItems
MsgBox strFilename
Next
End With
' Excel 2003 is a good filter choice: Excel Viewer, OpenOffice, + Excel versions can open these files
' If .Show = - 1 user picked at least one file
' The user pressed cancel.
' Assign strings to param locations from (1,2) to (7,2). This matches template
' Now using relative references to increase portability and NOT SELECTING the cells to increase macro speed, shorten code
With ActiveCell
.Offset(1, 2) = decPlateNo
.Offset(2, 2) = decStartrow
.Offset(3, 2) = decStartcol
.Offset(4, 2) = decColNo
.Offset(5, 2) = decStep
.Offset(6, 2) = strDirN
.Offset(7, 2) = strFileN
End With
' Measure of efflux of 2 plates of scint-40
M40Eff = 4.37
M40Eff = 2.4
' Select and copy data and range
Range("A1:O22").Select
Selection.Copy
MsgBox "start"
' Use the array
For decInd = 1 To decPlateNo / 2 - 1
decRowIn = 1 + decStep * 2 * decInd
decRangeNIn = "A" + CStr(decRowIn)
Range(decRangeNIn).Select
ActiveSheet.Paste
Next decInd 'Go to next indice
Application.CutCopyMode = False ' Have the data in both sheets
Workbooks.OpenText Filename:=vCPath _
, Origin:=437, StartRow:=1, DataType:=xlDelimited, TextQualifier:= _
xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=False, Semicolon:=False _
, Comma:=True, Space:=False, Other:=False, FieldInfo:=Array(Array(1, 1), _
Array(2, 1), Array(3, 1), Array(4, 1), Array(5, 1), Array(6, 1), Array(7, 1), Array(8, 1), _
Array(9, 1), Array(10, 1), Array(11, 1), Array(12, 1), Array(13, 1)), _
TrailingMinusNumbers:=True
For decInd1 = 1 To decPlateNo 'Between these 2 columns
decTLCorn = "B" + CStr(decStartrow + (decInd1 - 1) * decStep)
decBRCorn = "M" + CStr(decStartrow + 7 + (decInd1 - 1) * decStep)
decRangeNOut = decTLCorn + ":" + decBRCorn
decRangeNIn = decTLCorn
Windows(vFileN).Activate
Range(vRangeNOut).Select
Selection.Copy
Windows(strtemp_name).Activate
Sheets("Data").Select
Range(vRangeNIn).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Next decInd1
' Operation:=xlNone prevents calculations while pasting (less CPU intensive)
' Don't skip blanks, don't transpose
' Calculation of background and efflux for individual plates
For decInd1 = 1 To decPlateNo / 2
decStep2 = (decInd1 - 1) * decStep * 2
decBgrRow = decStartrow + 8 + decStep2
decBgrValP = Cells(decBgrRow, 2).Value 'Background plate value
For decInd2 = 0 To 7 'From column Ind2 to column 7 do multiplication
decEntryRow = decStartrow + decInd2 + decStep2
decEntryRow2 = decStartrow + decInd2 + decStep2 + 11
decMediaVal = Cells(decEntryRow, 13).Value
decMonoVal = Cells(decEntryRow2, 13).Value
Cells(decEntryRow, 15).Value = decMEeff * 100 * decVolcorr * (decMediaVal - decBgrValP) / (decM40eff * decMonoVal + decVolcorr * decMEeff * (decMediaVal - decBgrValP))
Next decInd2
Next decInd1
MsgBox "end"
' calculation of average background for all media plates
decBgrSum = 0
For decInd1 = 1 To decPlateNo / 2
decStep2 = (decInd1 - 1) * decStep * 2
For decInd2 = 0 To 7
decRowIn = decStartrow + decStep2 + decInd2
decBgrSum = decBgrSum + Cells(decRowIn, 2).Value
Next decInd2
Next decInd1
decBgrVal = decBgrSum / (4 * decPlateNo) 'The plates are split up into 4 (control (media) plates are 2 of them).
decBgrVal = Cells(2, 17).Value
' Rearanging data and transferring to Results sheet
decMxRNo = 8 * decColNo
ReDim vResMatrix(1 To decMxRNo, 1 To decPlateNo)
Sheets("Data").Select
For decInd1 = 1 To decPlateNo
decMcol = decInd1
For decInd2 = 1 To 8
decRowIn = (decInd1 - 1) * decStep + decStartrow + decInd2 - 1
For decInd3 = 1 To decColNo
decColIn = decStartcol + decInd3 - 1
decMRow = (decInd3 - 1) * 8 + decInd2
vResMatrix(decMRow, decMcol) = Cells(decRowIn, decColIn).Value
Next decInd3
Next decInd2
Next decInd1
Sheets("Results").Select
For decInd4 = 1 To decPlateNo
For decInd5 = 1 To decMxRNo
Cells(decInd5, decInd4).Value = vResMatrix(decInd5, decInd4) 'Put the values of the matrix in this range?
Next decInd5
Next decInd4
Sheets("Results QC").Select
' Select QC (quality control) calculation
Range("C81:C82").Select
Selection.Copy
For decInd = 1 To decPlateNo / 2 - 1
decColIn = 2 + 2 * decInd + 1
Cells(81, decColIn).Select
ActiveSheet.Paste 'Paste values of the active sheet (C81:C82 range)
Next decInd
For decInd4 = 1 To decPlateNo
decInd6 = decInd4 + 2
For decInd5 = 1 To decMxRNo 'Put these cell values in the matrix
Cells(decInd5, decInd6).Value = vResMatrix(decInd5, decInd4)
Next decInd5
Next decInd4
For decInd4 = 1 To decPlateNo
decInd6 = decInd4 + 2
decMeanComp = 0.6 * Cells(81, decInd6).Value
For decInd5 = 1 To decMxRNo
If Cells(decInd5, decInd6).Value < decMeanComp Then
Cells(decInd5, decInd6).Interior.Color = RGB(255, 0, 0)
' If the cell value is less than the average highlight them red as outliers. (More likely: from pipettes that didn't release)
ElseIf Cells(decInd5, decInd6).Value > decMeanComp Then
Cells(decInd5, decInd6).Interior.Color = RGB(7, 253, 56)
' If the cell value is greater than the average highlight them green as outliers. (Unlikely unless )
End If
Next decInd5
Next decInd4
MsgBox "4"
ErrorHandler:
MsgBox "Error Code" & Err.Number & vbNewLine & Err.Description, vbCritical, "Error Code" & Err.Number
End Sub
' Another function to continue arranging the data. Start by declaring all data types.
Sub Arrange_data()
On Error GoTo ErrorHandler
Dim strPath, strFileN, strDirN, strCPath, strRangeNOut, strRangeNIn, strTLCorn, strBRCorn As String
Dim decColIn4: decColIn4 = CDec(decColIn4)
Dim decInd5: decInd5 = CDec(decInd5)
Dim decInd6: decInd6 = CDec(decInd6)
Dim decPlateNo: decPlateNo = CDec(decPlateNo)
Dim decStartrow: decStartrow = CDec(decStartrow)
Dim decStartcol: decStartcol = CDec(decStartcol)
Sheets("Parameters").Select
decPlateNo = Cells(1, 2).Value
decStartrow = Cells(2, 2).Values
decStartcol = Cells(3, 2).Value
decColNo = Cells(4, 2).Value
decStep = Cells(5, 2).Value
decMEeff = 2.03
decM40eff = 4.37 'microscint 40=kind of solution the macrophages go in
decVolcorr = 2.4
decMxRNo = 8 * decColNo
ReDim vResMatrix(1 To decMxRNo, 1 To decPlateNo)
' Select QC (quality control) data
Sheets("Results QC").Select
For decInd1 = 1 To decPlateNo
decInd3 = decInd1 + 2
For decInd2 = 1 To iMxRNo
vResMatrix(decInd2, decInd1) = Cells(decInd2, decInd3).Value
Next decInd2
Next decInd1
' Transfer data for two methods of efflux calculations.
' Create template of columns.
Sheets("Processed indiv").Select
Range("C2:E87").Select
Selection.Copy
For decInd = 1 To decPlateNo / 2 - 1
decColIn = 3 + 3 * decInd
Cells(2, decColIn).Select
ActiveSheet.Paste
Next decInd
Application.CutCopyMode = False
' Don't cut and copy: leave the values in the Excel sheet.
' For disgorging values stored in matrix and calculate efflux.
For decInd1 = 1 To decPlateNo / 2
decColIn1 = 3 + 3 * (decInd1 - 1)
decColIn2 = decColIn1 + 1
decColIn3 = decColIn1 + 2
decBgrRow = (decInd1 - 1) * decStep * 2 + decStartrow + 8
decInd4 = 2 * decInd1
decInd3 = decInd4 - 1
Cells(1, decStartcol + 3 * (decInd1 - 1)).Value = "Plate " + CStr(decInd1)
' Get background value for the plate.
Sheets("Data").Select
decBgrValP = Cells(decBgrRow, 2)
Sheets("Processed indiv").Select
' Digorging values and calculating efflux.
For decInd2 = 1 To iMxRNo
decMediaVal = vResMatrix(decInd2, decInd3)
decMonoVal = vResMatrix(decInd2, decInd4)
Cells(2 + decInd2, decColIn1).Value = decMediaVal
Cells(2 + decInd2, decColIn2).Value = decMonoVal
Cells(2 + decInd2, decColIn3).Value = decMEeff * 100 * decVolcorr * (decMediaVal - decBgrValP) / (decM40eff * decMonoVal + decVolcorr * decMEeff * (decMediaVal - decBgrValP))
Next decInd2
Next decInd1
' Remove no data cells.
For decInd1 = 1 To decPlateNo / 2
decColIn1 = 3 + 3 * (decInd1 - 1)
For decInd2 = 3 To decMxRNo + 2
If Cells(decInd2, decColIn1).Value = "" Then
Cells(decInd2, decColIn1 + 1).Value = ""
Cells(decInd2, decColIn1 + 2).Value = ""
End If
Next decInd2
Next decInd1
' calculate data based on plate average.
' Create template for columns.
Sheets("Processed by plate").Select
Range("C2:E87").Select
Selection.Copy
For decInd = 1 To decPlateNo / 2 - 1
decColIn = 3 + 3 * decInd
Cells(2, decColIn).Select
ActiveSheet.Paste
Next decInd
Application.CutCopyMode = False
' Prep for disgorging values stored in matrix and calculate efflux.
For decInd1 = 1 To decPlateNo / 2
decColIn1 = 3 + 3 * (decInd1 - 1)
decColIn2 = decColIn1 + 1
decColIn3 = decColIn1 + 2
decBgrRow = (decInd1 - 1) * decStep * 2 + decStartrow + 8
decInd4 = 2 * decInd1
decInd3 = decInd4 - 1
Cells(1, decStartcol + 3 * (decInd1 - 1)).Value = "Plate " + CStr(decInd1)
' Get background value for the plate.
Sheets("Data").Select
decBgrValP = Cells(decBgrRow, 2)
Sheets("Processed by plate").Select
' Digorging values and calculating efflux.
' When does this for loop end?
For decInd2 = 1 To decMxRNo
Cells(2 + decInd2, decColIn1).Value = vResMatrix(decInd2, decInd3)
Cells(2 + decInd2, decColIn2).Value = vResMatrix(decInd2, decInd4)
Next decInd2
' Get average value for monolayer. (Cells are in 1-cell deep layer.) ?
decMonoVal = Cells(83, decColIn2).Value
For decInd2 = 1 To decMxRNo
decMediaVal = vResMatrix(decInd2, decInd3)
Cells(2 + decInd2, decColIn3).Value = decMEeff * 100 * decVolcorr * (decMediaVal - decBgrValP) / (decM40eff * decMonoVal + decVolcorr * decMEeff * (decMediaVal - decBgrValP))
Next decInd2
Next decInd1
' Remove no data cells.
For decInd1 = 1 To decPlateNo / 2
decColIn1 = 3 + 3 * (decInd1 - 1)
For decInd2 = 3 To decMxRNo + 2
If Cells(decInd2, decColIn1).Value = "" Then
Cells(decInd2, decColIn1 + 1).Value = ""
Cells(decInd2, decColIn1 + 2).Value = ""
End If
Next decInd2
Next decInd1
' Replace cell count data with calculated efflux in the matrix.
Sheets("Processed indiv").Select
For decInd1 = 1 To decPlateNo / 2
decColIn1 = 5 + 3 * (decInd1 - 1)
decInd4 = 2 * decInd1
For decInd2 = 1 To decMxRNo
vResMatrix(decInd2, decInd4) = Cells(2 + decInd2, decColIn1).Value
Next decInd2
Next decInd1
'Move data to duplicate comparison.
Sheets("Duplicate comparison").Select
Range("C2:N87").Select
Selection.Copy
For decInd = 1 To decPlateNo / 4 - 1
decColIn = 3 + 12 * decInd
Cells(2, decColIn).Select
ActiveSheet.Paste
Next decInd
Application.CutCopyMode = False
For decInd1 = 1 To decPlateNo / 4
decColIn1 = 3 + 12 * (decInd1 - 1)
decColIn2 = decColIn1 + 2
decColIn3 = decColIn1 + 3
decColIn4 = decColIn1 + 5
decInd3 = decInd1 * 4 - 3
decInd4 = decInd3 + 1
decInd5 = decInd3 + 2
decInd6 = decInd3 + 3
Cells(1, decStartcol + 12 * (decInd1 - 1)).Value = "Plate " + CStr(2 * decInd1 - 1)
Cells(1, decStartcol + 3 + 12 * (decInd1 - 1)).Value = "Plate " + CStr(2 * decInd1)
For iInd2 = 1 To iMxRNo
Cells(2 + iInd2, iColIn1).Value = vResMatrix(decInd2, decInd3)
Cells(2 + iInd2, iColIn2).Value = vResMatrix(decInd2, decInd4)
Cells(2 + iInd2, iColIn3).Value = vResMatrix(decInd2, decInd5)
Cells(2 + iInd2, iColIn4).Value = vResMatrix(decInd2, decInd6)
Next decInd2
Next decInd1
' Remove no data cells.
For decInd1 = 1 To decPlateNo / 4
decColIn1 = 3 + 12 * (decInd1 - 1)
decColIn2 = decColIn1 + 3
For decInd2 = 3 To decMxRNo + 2
If Cells(decInd2, decColIn1).Value = "" Then
Cells(decInd2, decColIn1 + 1).Value = ""
For decInd = 1 To 6
Cells(decInd2, decColIn1 + 5 + decInd).Value = ""
Next decInd
End If
If Cells(decInd2, decColIn2).Value = "" Then
Cells(decInd2, decColIn2 + 1).Value = ""
For decInd = 1 To 6
Cells(decInd2, decColIn2 + 2 + decInd).Value = ""
Next iInd
End If
Next decInd2
Next decInd1
' Prepare summary statistics.
decTL = decPlateNo * decMxRNo / 2
ReDim vResMatrix(1 To 4, 1 To iTL)
Sheets("Processed indiv").Select
decRowIn = 3 + decMxRNo
decRowIn2 = decRowIn + 1
For decInd1 = 1 To 3 * decPlateNo / 2
For decInd2 = 1 To 3
decRowIn3 = 3 * (decInd1 - 1) + iInd2
decColIn = 2 + decRowIn3
vResMatrix(1, decRowIn3) = Cells(decRowIn, decColIn).Value
vResMatrix(2, decRowIn3) = Cells(decRowIn2, decColIn).Value
Next decInd2
Next decInd1
Sheets("Processed by plate").Select
decRowIn = 3 + iMxRNo
decRowIn2 = decRowIn + 1
For decInd1 = 1 To 3 * decPlateNo / 2
For decInd2 = 1 To 3
decRowIn3 = 3 * (decInd1 - 1) + decInd2
decColIn = 2 + decRowIn3
vResMatrix(3, iRowIn3) = Cells(decRowIn, decColIn).Value
vResMatrix(4, decRowIn3) = Cells(decRowIn2, decColIn).Value
Next decInd2
Next decInd1
' Put summary statistics in distribution comp.
Sheets("Distribution comp").Select
For decInd = 1 To 3 * decPlateNo / 2
Cells(2 + iInd, 2).Value = vResMatrix(1, iInd)
Cells(2 + iInd, 3).Value = vResMatrix(2, iInd)
Cells(2 + iInd, 5).Value = vResMatrix(3, iInd)
Cells(2 + iInd, 6).Value = vResMatrix(4, iInd)
Next decInd
' Prepare plate by plate results.
Sheets("Duplicate comparison").Select
For decInd = 1 To iPlateNo / 4
decMatrixStep = (iInd - 1) * iMxRNo
decColIn = 9 + 12 * (iInd - 1)
decColIn2 = iColIn + 2
decColIn3 = iColIn + 1
decColIn4 = iColIn + 3
For decInd2 = 1 To decMxRNo
decMRow = iMatrixStep + decInd2
' Difference between duplicates converted into range.
vResMatrix(1, iMRow) = Cells(2 + decInd2, decColIn).Value
vResMatrix(2, iMRow) = Cells(2 + decInd2, decColIn2).Value / 2
vResMatrix(3, iMRow) = Cells(2 + decInd2, decColIn3).Value
vResMatrix(4, iMRow) = Cells(2 + decInd2, decColIn4).Value / 2
Next decInd2
Next decInd
' Transfer data to Summary.
Sheets("Summary").Select
' Prepare sheet.
Range("B3:G82").Select
Selection.Copy
For decInd = 1 To decPlateNo / 4 - 1
decRowIn = 3 + decMxRNo * iInd
decRangeNIn = "B" + CStr(decRowIn)
Range(decRangeNIn).Select
ActiveSheet.Paste
For decInd2 = 1 To decMxRNo
Cells(decInd2 + decRowIn - 1, 1).Value = "Plate " + CStr(decInd + 1)
Next decInd2
Next decInd
Application.CutCopyMode = False
' Don't cut and copy
' Distribute values.
For decInd = 1 To decTL
iRowIn = iInd + 2
Cells(decRowIn, 4).Value = vResMatrix(1, decInd)
Cells(decRowIn, 5).Value = vResMatrix(2, decInd)
Cells(decRowIn, 6).Value = vResMatrix(3, decInd)
Cells(decRowIn, 7).Value = vResMatrix(4, decInd)
Next decInd
' Transfer data to Matrix summary.
Sheets("Matrix summary").Select
' Prepare page for data.
Range("A1:M11").Select
Selection.Copy
For decInd = 1 To decPlateNo / 4 - 1
decRowIn = 1 + decStep * decInd
decRangeNIn = "A" + CStr(decRowIn)
Range(decRangeNIn).Select
ActiveSheet.Paste
Next decInd
Application.CutCopyMode = False
' Distribute data.
For decInd1 = 0 To iPlateNo / 4 - 1
decPlateStep = decStep * decInd1
decMatrixStep = iColNo * 8 * decInd1
For decInd2 = 0 To iColNo - 1
decColIn = decStartcol + decInd2
decColStep = 8 * iInd2
For iInd3 = 0 To 7
iRowIn = iStartrow + iPlateStep + iInd3
iMxElem = iMatrixStep + iColStep + iInd3 + 1
Cells(decRowIn, decColIn).Value = vResMatrix(3, iMxElem)
Next decInd3
Next decInd2
Next decInd1
' collect statistical parameters on efflux for unknown samples.
decRowNo = decPlateNo / 4
ReDim decEffluxMatrix(1 To iRowNo, 1 To 6)
decStartRowIn = 10
decStartColIn = 2
For decInd = 0 To iRowNo - 1
decRowIn = iStartRowIn + iStep * iInd
EffluxMatrix(iInd + 1, 1) = Cells(iRowIn, iStartColIn).Value
EffluxMatrix(iInd + 1, 2) = Cells(iRowIn + 1, iStartColIn).Value
Next decInd
'collect statistical parameters on efflux for control samples.
Sheets("Data").Select
decStartRowIn = 10
decStartColIn = 15
For iInd = 0 To iRowNo - 1
iRowIn = iStartRowIn + iStep * iInd * 4
EffluxMatrix(iInd + 1, 3) = Cells(iRowIn, iStartColIn).Value
EffluxMatrix(iInd + 1, 4) = Cells(iRowIn + 1, iStartColIn).Value
EffluxMatrix(iInd + 1, 5) = Cells(iRowIn + 22, iStartColIn).Value
EffluxMatrix(iInd + 1, 6) = Cells(iRowIn + 23, iStartColIn).Value
Next decInd
' Ouput of statistical parameters on efflux
Sheets("Matrix summary").Select
decStartRowOut = 4
decStartColOut = 15
For decInd1 = 1 To decRowNo
decRowOut = decStartRowOut + decInd1 - 1
For decInd2 = 1 To 6
decColOut = decStartColOut + decInd2 - 1
Cells(decRowOut, decColOut).Value = EffluxMatrix(decInd1, decInd2)
Next iInd2
Next decInd1
'Output into Matrix min-max
Sheets("Matrix min-max").Select
For decInd1 = 0 To decPlateNo / 4 - 1
decPlateStep = decStep * decInd1
decMatrixStep = decColNo * 8 * decInd1
For decInd2 = 0 To decColNo - 1
decColIn = decStartcol + iInd2
decColStep = 8 * decInd2
For decInd3 = 0 To 7
decRowIn = decStartrow + decPlateStep + decInd3
decMxElem = decMatrixStep + decColStep + decInd3 + 1
Cells(decRowIn, decColIn).Value = vResMatrix(3, decMxElem)
Next decInd3
Next decInd2
Next decInd1
ErrorHandler:
MsgBox "Error detected" & vbNewLine & "Error" & Err.Number & ": " & Err.Description, vbCritical, "Error Handler: Error " & Err.Number
MsgBox "If you want to force the program to run, go to the line below and insert a ' mark to comment the line out." & vbNewLine & "On Error GoTo ErrorHandler", vbCritical, "Error Handler: Error " & Err.Number
End Sub
答案 0 :(得分:3)
您在初始化变量之前尝试使用变量vCPath
。