I was using the script which I found here : https://excelribbon.tips.net/T008349_Counting_All_Characters.html
It is working as expected however when there are some other objects like pictures, the script returns me the error 438"Object Doesn't Support This Property or Method".
When I deleted the pictures the script was working well again.
Is there an option to put in the script something like "ignore pictures"? Or is there any better type of script to achieve this? I am not good at all at VBA, all help will be much appreciated.
Here's a simplified approach that may work out a bit better. I think being explicit which Shape Types you want to count is going to be a cleaner way of going about this.
Option Explicit
Private Function GetCharacterCount() As Long
Dim wks As Worksheet
Dim rng As Range
Dim cell As Range
Dim shp As Shape
For Each wks In ThisWorkbook.Worksheets
For Each shp In wks.Shapes
'I'd only add the controls I care about here, take a look at the Shape Type options
If shp.Type = msoTextBox Then GetCharacterCount = GetCharacterCount + shp.TextFrame.Characters.Count
Next
On Error Resume Next
Set rng = Union(wks.UsedRange.SpecialCells(xlCellTypeConstants), wks.UsedRange.SpecialCells(xlCellTypeFormulas))
On Error GoTo 0
If not rng Is Nothing Then
For Each cell In rng
GetCharacterCount = GetCharacterCount + Len(cell.Value)
Next
end if
Next
End Function
Sub CountCharacters()
Debug.Print GetCharacterCount()
End Sub
It looks like you can add an if-check like the one here (VBA Code to exclude images png and gif when saving attachments for "PNG" and "GIF".).
You just have to change the if-check to check for the picture type you're using "JPG" or "JPEG"? Simply match the extension to the if-check by replacing "PNG" or "GIF" with your extension in CAPS.
Add the if-check right above where the error is occurring or better yet, add it above the scope of where the error is occurring.
I took the script from your link and modified it. Now it works.
It's far from perfect (there're some cases where it can still crash), but now it supports handling Shapes with no .TextFrame property:
Sub CountCharacters()
Dim wks As Worksheet
Dim rng As Range
Dim rCell As Range
Dim shp As Shape
Dim bPossibleError As Boolean
Dim bSkipMe As Boolean
Dim lTotal As Long
Dim lTotal2 As Long
Dim lConstants As Long
Dim lFormulas As Long
Dim lFormulaValues As Long
Dim lTxtBox As Long
Dim sMsg As String
On Error GoTo ErrHandler
Application.ScreenUpdating = False
lTotal = 0
lTotal2 = 0
lConstants = 0
lFormulas = 0
lFormulaValues = 0
lTxtBox = 0
bPossibleError = False
bSkipMe = False
sMsg = ""
For Each wks In ActiveWorkbook.Worksheets
' Count characters in text boxes
For Each shp In wks.Shapes
If TypeName(shp) <> "GroupObject" Then
On Error GoTo nextShape
lTxtBox = lTxtBox + shp.TextFrame.Characters.Count
End If
nextShape:
Next shp
On Error GoTo ErrHandler
' Count characters in cells containing constants
bPossibleError = True
Set rng = wks.UsedRange.SpecialCells(xlCellTypeConstants)
If bSkipMe Then
bSkipMe = False
Else
For Each rCell In rng
lConstants = lConstants + Len(rCell.Value)
Next rCell
End If
' Count characters in cells containing formulas
bPossibleError = True
Set rng = wks.UsedRange.SpecialCells(xlCellTypeFormulas)
If bSkipMe Then
bSkipMe = False
Else
For Each rCell In rng
lFormulaValues = lFormulaValues + Len(rCell.Value)
lFormulas = lFormulas + Len(rCell.Formula)
Next rCell
End If
Next wks
sMsg = Format(lTxtBox, "#,##0") & _
" Characters in text boxes" & vbCrLf
sMsg = sMsg & Format(lConstants, "#,##0") & _
" Characters in constants" & vbCrLf & vbCrLf
lTotal = lTxtBox + lConstants
sMsg = sMsg & Format(lTotal, "#,##0") & _
" Total characters (as constants)" & vbCrLf & vbCrLf
sMsg = sMsg & Format(lFormulaValues, "#,##0") & _
" Characters in formulas (as values)" & vbCrLf
sMsg = sMsg & Format(lFormulas, "#,##0") & _
" Characters in formulas (as formulas)" & vbCrLf & vbCrLf
lTotal2 = lTotal + lFormulas
lTotal = lTotal + lFormulaValues
sMsg = sMsg & Format(lTotal, "#,##0") & _
" Total characters (with formulas as values)" & vbCrLf
sMsg = sMsg & Format(lTotal2, "#,##0") & _
" Total characters (with formulas as formulas)"
MsgBox Prompt:=sMsg, Title:="Character count"
ExitHandler:
Application.ScreenUpdating = True
Exit Sub
ErrHandler:
If bPossibleError And Err.Number = 1004 Then
bPossibleError = False
bSkipMe = True
Resume Next
Else
MsgBox Err.Number & ": " & Err.Description
Resume ExitHandler
End If
End Sub
You could try:
Option Explicit
Sub test()
Dim NoOfChar As Long
Dim rng As Range, cell As Range
NoOfChar = 0
For Each cell In ThisWorkbook.Worksheets("Sheet1").UsedRange '<- Loop all cell in sheet1 used range
NoOfChar = NoOfChar + Len(cell.Value) '<- Add cell len to NoOfChar
Next cell
Debug.Print NoOfChar
End Sub
Related
Hi If I have a range of data from A1:E1 and I want to copy and paste in the same sheet with incrementing both the column and row (in another word paste them diagonally), anyone can help with this vba?
my current code is this but this code only paste to B2:F2... i want to paste the data until row number 3500.. (with incrementing row and column).. data in A1:E1 is fix, so i would like to paste them to B2:F2, C3:G3, D4:H4 etc..
Sub m1()
Worksheets("Sheet1").Range("A1:E1").Copy
last_row = Worksheets("Sheet1").Range("B" & Worksheets("Sheet1").Rows.Count).End(xlUp).Row + 1
If last_row > 100000 Then last_row = 1
Worksheets("Sheet1").Range("B" & last_row).PasteSpecial
End Sub
There is no build-in function to copy diagonally. You will need to loop over all rows and copy the data individually.
The following piece of code shows you how that could look like
Const MaxRows = 3500
With Worksheets("Sheet1")
Dim r As Range
Set r = .Range("A1:E1")
r.Copy
Dim offset As Long
For offset = 1 To MaxRows
r.offset(offset, offset).PasteSpecial
Next
End With
However, this will be painfully slow. If you just want to copy data, you can change the code to
With Worksheets("Sheet1")
Dim r As Range, data
Set r = .Range("A1:E1")
data = r.Value2
Dim offset As Long
For offset = 1 To MaxRows
r.offset(offset, offset).Value2 = data
Next
End With
Copy Diagonally Using the Range.Copy Method
The Code
Option Explicit
Sub CopyDiagonallyTEST()
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
CopyDiagonally wb, "Sheet1", "A1:E1", 3499, 1, 1
' Note that you could omit the last two argument's parameters
' since they are optional and by default equal to 1.
End Sub
Sub CopyDiagonally( _
ByVal wb As Workbook, _
ByVal WorksheetName As String, _
ByVal SourceRangeAddress As String, _
Optional ByVal NumberOfCopies As Long = 1, _
Optional ByVal RowOffset As Long = 1, _
Optional ByVal ColumnOffset As Long = 1)
Const ProcName As String = "CopyDiagonally"
Dim dt As Double: dt = Timer ' measure duration
Dim n As Long
Dim LastAddress As String
Dim AnErrorOccurred
On Error GoTo ClearError
Dim ws As Worksheet: Set ws = wb.Worksheets(WorksheetName)
Dim srg As Range: Set srg = ws.Range(SourceRangeAddress)
Dim drg As Range: Set drg = srg
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
For n = 1 To NumberOfCopies
Set drg = drg.Offset(RowOffset, ColumnOffset)
LastAddress = drg.Address(0, 0) ' keep track in case of an error
srg.Copy drg
Next n
ProcExit:
On Error Resume Next
If Not Application.ScreenUpdating Then
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End If
dt = Timer - dt
Dim tString As String: tString = Format(dt, "0.###") & " seconds"
Dim MsgString As String
MsgString = "Diagonally Copying Stats" & vbLf & vbLf _
& "Source Range Address: '" & SourceRangeAddress & "'" & vbLf _
& "Number of Copies Created: " & n - 1 & " (" _
& NumberOfCopies & ")" & vbLf _
& "Last Range Address: '" & LastAddress & "'" & vbLf _
& "Operation Duration: " & tString
MsgBox MsgString, _
IIf(AnErrorOccurred, vbCritical, vbInformation), ProcName
Debug.Print MsgString
On Error GoTo 0
Exit Sub
ClearError:
Debug.Print "'" & ProcName & "' Run-time error '" _
& Err.Number & "':" & vbLf & " " & Err.Description
AnErrorOccurred = True
Resume ProcExit
End Sub
Results in the Immediate Window
Results for CopyDiagonally wb, "Sheet1", "A1:E1", 3499, 1, 1 (Requested)
Diagonally Copying Stats
Source Range Address: 'A1:E1'
Number of Copies Created: 3499 (3499)
Last Range Address: 'EDP3500:EDT3500'
Operation Duration: 34.305 seconds
Results for CopyDiagonally wb, "Sheet1", "A1:E1", 3499, 1, 500
(an error occurs since there are only 16384 columns)
'CopyDiagonally' Run-time error '1004':
Application-defined or object-defined error
Diagonally Copying Stats
Source Range Address: 'A1:E1'
Number of Copies Created: 163 (3499)
Last Range Address: 'XBY164:XCC164'
Operation Duration: 1.375 seconds
Please bear with me. My code is probably complete shit, so I appreciate all feedback! So what this does is, on my main workbook, there are a bunch of UNC hyperlinks in Row M, that link to files in a section drive.
What this code does:
Go down the list of hyperlinks in Column M, opens them up and executes the code inside of the "With WBSsource".
First, it searches for instances of the incorrect filepath (st) inside each of the cells formulas (NOT VALUES), and increments a counter using InStr (t), then after the worksheet has been searched, if the final count (c) is more than 0, meaning the search found at least one incorrect filepath, it will proceed to the next step.
It does a Cells.Replace on a worksheet (ws.) basis (at the FORMULA level)
Cells per worksheet are all done, it should save the workbook and close it before moving onto the next one.
Any links that could not be opened will appear in a final popup.
It is by Step 3 that it starts to run sluggish and crash.
I'm trying my best to get this automated and saving the workbooks. Then, once they're all updated, running this code again would be much faster cause it won't have to replace everything again.
Sub List_UpdateAndSave()
Dim lr As Long
Dim i As Integer
Dim WBSsource As Workbook
Dim FileNames As Variant
Dim msg As String
Dim ws As Worksheet
Dim r As Range, t As Long, c As Integer
' Update the individual credit models
With ThisWorkbook.ActiveSheet
lr = .Cells(.Rows.Count, "M").End(xlUp).Row
FileNames = .Range("M2:M" & lr).Value
End With
For i = LBound(FileNames, 1) To UBound(FileNames, 1)
On Error Resume Next
If FileNames(i, 1) Like "*.xls*" Then
Set WBSsource = Workbooks.Open(FileNames(i, 1), _
ReadOnly:=False, _
Password:="", _
UpdateLinks:=3)
If Err = 0 Then
With WBSsource
Application.DisplayAlerts = False
ActiveWorkbook.Final = False
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Application.EnableEvents = False
st = "\\corp\Accounts\" 'Search Phrase
n = "\\corp\StackOverflow\Accounts\" 'New Phrase
c = 0
For Each ws In WBSsource.Worksheets
ws.Activate
t = 0
On Error Resume Next
For Each r In ws.Cells.SpecialCells(xlCellTypeFormulas)
t = InStr(1, r.Formula, st)
If t > 0 Then
c = c + 1
End If
Next r
Next ws
If c > 0 Then
'MsgBox ws.Name & Chr(10) & (c)
ws.Cells.Replace st, n
End If
.UpdateLink Name:=ActiveWorkbook.LinkSources, Type:=xlExcelLinks
Application.EnableEvents = True
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
.Save
.Close True
End With
Else
msg = msg & FileNames(i, 1) & Chr(10) & Chr(10)
On Error GoTo 0
End If
End If
Set WBSsource = Nothing
Next i
If Len(msg) > 0 Then
'MsgBox "The Following Files Could Not Be Opened" & _
' Chr(10) & msg, 48, "Error"
Set objShell = CreateObject("Wscript.Shell")
objShell.Popup "The Following Files Could Not Be Opened" & _
Chr(10) & Chr(10) & msg, 48, "Error"
End If
Application.DisplayAlerts = True
End Sub
It's not completely crap. I just learned that we could create an array with this.
FileNames = .Range("M2:M" & lr).Value
It may crash since there's no range limit on the 3rd step. Try getting the last row and column on each worksheet, then create a range based on that.
With ws
' Get end cells
With .Cells.SpecialCells(xlCellTypeLastCell)
intLastRow = .Row
intLastCol = .Column
End With
For each r in .Range(.Cells(1,1), .Cells(intLastRow, intLastCol))
' Check formula if it contains specific string
t = InStr(1, r.Formula, st)
If t > 0 Then
c = c + 1
End If
' Replace formula with new string
r.Formula = Replace(r.Formula, st, n)
Next r
End With
Edit: Here's the full code. Let me know if this works for you.
Option Explicit
' Update the individual credit models
Sub List_UpdateAndSave()
With Application
.ScreenUpdating = False
.Calculation = xlCalculationManual
End With
On Error GoTo ErrorHandler
' Declaration
Dim i As Long
Dim arrLinks As Variant
Dim strLinksErr As String
' Initialization
Dim strPathCur As String: strPathCur = "\\corp\Accounts\" ' search phrase
Dim strPathNew As String: strPathNew = "\\corp\StackOverflow\Accounts\" ' new phrase
With ThisWorkbook.ActiveSheet
' Get links from sheet
arrLinks = .Range("M2:M" & .Cells.SpecialCells(xlCellTypeLastCell).Row).Value
End With
For i = LBound(arrLinks, 1) To UBound(arrLinks, 1)
' Check for Excel links
If VBA.InStr(1, arrLinks(i, 1), ".xls", vbTextCompare) > 0 Then
FnExcelUpdateLinks arrLinks(i, 1), strPathCur, strPathNew
Else
' Add to list of links that could not be opened
strLinksErr = strLinksErr & arrLinks(i, 1) & Chr(10)
End If
Next i
ErrorHandler:
' Display any errors
If Err.Number <> 0 Then MsgBox Err.Description, vbCritical, "Error " & Err.Number
' Display any non-Excel links
If strLinksErr <> "" Then
MsgBox "The following files could not be opened:" & _
Chr(10) & strLinksErr, 48, "Error"
End If
With Application
.ScreenUpdating = True
.Calculation = xlCalculationAutomatic
End With
End Sub
Function FnExcelUpdateLinks(ByVal strWbkPath As String, ByRef strPathCur As String, ByRef strPathNew As String)
Dim intLastRow As Long, intLastCol As Long
Dim wbkTmp As Workbook
Dim shtTmp As Worksheet
Dim rngCell As Range
' Open link as workbook
Set wbkTmp = Workbooks.Open(strWbkPath, ReadOnly:=False, Password:="", UpdateLinks:=3)
With wbkTmp
For Each shtTmp In .Worksheets
With shtTmp
' Get end cells
With .Cells.SpecialCells(xlCellTypeLastCell)
intLastRow = .Row
intLastCol = .Column
End With
For Each rngCell In .Range(.Cells(1, 1), .Cells(intLastRow, intLastCol))
If VBA.InStr(1, rngCell.Formula, strPathCur) > 0 Then
rngCell.Formula = Replace(rngCell.Formula, strPathCur, strPathNew)
End If
Next rngCell
End With
Next shtTmp
.UpdateLink Name:=.LinkSources, Type:=xlExcelLinks
.Save
.Close True
End With
End Function
New to all this but appreciate any help I can get.
Problem: I have a duty roster with initials and sometimes I want to highlight a specific person to see his/her schedule. The highlight consists of changing the font color and making it bold but I'd also like the cell color to change as well, to lets say light green. I do know that I can use the Search/Replace feature but I'd like a macro for this.
So far, I've managed to piece together an input box and I can change the font color and add 'bold' to the font (and other changes) but I haven't solved changing the cell color.
This is what I have so far:
Sub FindAndBold()
Dim sFind As String
Dim rCell As Range
Dim rng As Range
Dim lCount As Long
Dim iLen As Integer
Dim iFind As Integer
Dim iStart As Integer
On Error Resume Next
Set rng = ActiveSheet.UsedRange. _
SpecialCells(xlCellTypeConstants, xlTextValues)
On Error GoTo ErrHandler
If rng Is Nothing Then
MsgBox "There are no cells with text"
GoTo ExitHandler
End If
sFind = InputBox( _
Prompt:="Skriv in dina initialer", _
Title:="Dina initialer")
If sFind = "" Then
MsgBox "Du skrev inget"
GoTo ExitHandler
End If
iLen = Len(sFind)
lCount = 0
For Each rCell In rng
With rCell
iFind = InStr(.Value, sFind)
Do While iFind > 0
.Characters(iFind, iLen).Font.Bold = True
.Characters(iFind, iLen).Font.Color = RGB(255, 0, 0)
.Characters(iFind, iLen).Font.ColorIndex = 4
lCount = lCount + 1
iStart = iFind + iLen
iFind = InStr(iStart, .Value, sFind)
Loop
End With
Next
If lCount = 0 Then
MsgBox "Fanns inget" & _
vbCrLf & "' " & sFind & " '" & _
vbCrLf & "att markera"
ElseIf lCount = 1 Then
MsgBox "Det fanns en" & _
vbCrLf & "' " & sFind & " '" & _
vbCrLf & "markerades"
Else
MsgBox lCount & " hittade" & _
vbCrLf & "' " & sFind & " '" & _
vbCrLf & "och markerades"
End If
ExitHandler:
Set rCell = Nothing
Set rng = Nothing
Exit Sub
ErrHandler:
MsgBox Err.Description
Resume ExitHandler
Any help would be greatly appreciated!
(The text in the prompt and response is in Swedish)
You can also do this using conditional formatting, no need for VBS.
Using a conditional format formula you can enter something like this: =AND(ISNUMBER(SEARCH($G$1;A2));$G$1<>"") - in this case field G1 would be the field used for searching (read:highlighting) all the fields containing this condition.
If you desire a VBS we can improve and include a filter for all lines matching your search:
Sub searchfilter()
Range("A11:M10000").AdvancedFilter Action:=xlFilterInPlace, CriteriaRange:= _
Range("A2:M13"), Unique:=False
End Sub
And to clear:
Sub clearfilter()
On Error Resume Next
ActiveSheet.ShowAllData
On Error GoTo 0
End Sub
Assign both macros to a button.
Sample image where i combined both (filter was done on C15 in this case):
And sample with hidden fields shown:
Function copyHeader(inputrange As String, inputsheet As String, outputcell As String, outputsheet As String)
Sheets(inputsheet).Range(inputrange).Copy Destination:=Sheets(outputsheet).Range(outputcell)
Application.CutCopyMode = False
Cells(1, 1).Value = 4 'probably better to make this dynamic
End Function
Function copyDetail(inputrange As String, inputsheet As String, outputcell As String, outputsheet As String)
Sheets(inputsheet).Range(inputrange).Copy Destination:=Sheets(outputsheet).Range(outputcell)
Application.CutCopyMode = False
Cells(1, 1).Value = 4 'probably better to make this dynamic
End Function
Function createTab(tabname As String)
Worksheets.Add.Name = tabname
End Function
Function shtExists(shtname As String) As Boolean
Dim sht As Worksheet
On Error GoTo ErrHandler:
Set sht = Sheets(shtname)
shtExists = True
ErrHandler:
If Err.Number = 9 Then
shtExists = False
End If
End Function
Public Function lastCell(Col As String)
With ActiveSheet
lastCell = .Cells(.Rows.Count, Col).End(xlUp).Row
End With
End Function
Sub AddData()
Dim teamname As String
Dim countery As Integer
Dim teamdata As String
Dim matchcounter As String
Dim resp As Boolean
Dim maxCounter As Integer
counter = 4
maxCounter = lastCell("B")
On Error GoTo eh
For counter = 4 To maxCounter
ThisWorkbook.Sheets("DataEntry").Select
teamdata = "C" & counter & ":" & "N" & counter
teamname = ThisWorkbook.Sheets("DataEntry").Range("B" & counter).Value
resp = shtExists(teamname)
If resp = False Then
createTab (teamname)
copyHeader "C1:M3", "DataEntry", "B1", teamname
matchcounter = CStr(Sheets(teamname).Range("A1").Value)
copyDetail teamdata, "DataEntry", "B" & matchcounter, teamname
ElseIf resp = True Then
copyDetail teamdata, "DataEntry", "B" & matchcounter, teamname
End If
Next counter
Worksheets("DataEntry").Activate
Done:
Exit Sub
eh:
MsgBox "The following error occurred: " & Err.Description & " " & Err.Number & " " & Err.Source
End Sub
So When I try and Run this as you saw from the title I get an Application-defined or object-defined error: 1004. I a, trying to make it iterate through cells B4 to B9 and at each one and if there is no sheet with the name in that cell it creates it and pastes the headers that are on the data entry page (C1:M3) and the data on that row from C to I onto the newly created sheet. If it does exist it looks at A1 of the sheet with that name and pastes the data into column B and the row that A1 specifies. And it does this for B4:B9 on each cell. Any help would be appreciated.
Dim teamdata As String
stringcombine = "C" & countery & ":" & "M" & countery
teamdata = Range(stringcombine)
Here you are assigning an array (of 11 entries) to a string, hence the type mismatch.
Upon reading your code, what you meant to do was
teamdata = Range(stringcombine).Address
though it wasn't necessary to create an additional variable teamdata for the address, you already had it in stringcombine.
Looking at the copypaste function, it appears that inputRange parameter should have a string value like "C3:M3". You pass teamdata to copypaste as the inputrange parameter, so are you expecting teamdata to have a value like "C3:M3"? If so, then your line
teamdata = Range(stringcombine)
could be
teamdata = stringcombine
What the current line attempts to do is take the values from the range of cells and assign them to a string variable -- which it isn't designed to do. If stringcombine were something like "M3" it would work ok. One cell value to one string.
Error 13 generally means you're trying to assign a value to a variable that can't accept that data type, or you're trying to pass the wrong data type as an argument to a sub or function.
If I've understood your requirements, this should be able to replace your existing code:
Sub AddData_ReWrite()
Dim teamName As String
Dim i As Integer
Dim matchCounter As String
Dim dataEntry As Excel.Worksheet
matchCounter = Range("A1").Value
Set dataEntry = Sheets("DataEntry")
For i = 4 To 9
teamName = Sheets("DataEntry").Range("B" & i).Value
CreateSheetIfNotExists teamName
Sheets(teamName).Range("B" & matchCounter & ":N" & matchCounter).Value = dataEntry.Range("C" & i & ":M" & i).Value
Next
dataEntry.Activate
End Sub
Sub CreateSheetIfNotExists(ByVal sheetName As String)
Dim sht As Worksheet
On Error GoTo ErrHandler:
Set sht = Sheets(sheetName)
ErrHandler:
If (Err.Number) Then
If Err.Number = 9 Then
With Worksheets.Add
.Name = sheetName
.Range("B1:N3").Value = Sheets("DataEntry").Range("C1:M3").Value
.Range("A1").Value = 2
End With
Else
'// What if it isn't error 9?
MsgBox "Error " & Err.Number & ":" & vbCrLf & vbCrLf & Err.Description, vbExclamation + vbOKOnly, "Error"
End If
End If
'// clear errors and reset error handler
Err.Clear
On Error GoTo 0
End Sub
I've tidied it up a bit to improve the readability and added extra error handling in your other sub routine.
The following code opens selected files, one at a time; if a file contains specific text string in B11 (there are four variation: LS2A, LS1PRA, LS1A and LSM12), specified data from Sheet(1) of each file is copied into an array. The search is performed by function “SearchFor” that is called in the main routine.
The array ArrCopy is filled with data from each file and should output into one of the four sheets in Master Workbook(SABI, SABII,LSM or LPRI&II). The output sheet is determined by the text string in B11 of each file.
I can’t get data to output to Master workbook for some reason. I've tried Debug.Print each array item after it's filled and I can see that the array is filled with correct data but I can't get the values to tranfer to the master workbook. The code runs but nothing is outputed on the worksheet.
Please suggest how to make this work. Thanks
Option Explicit
Function SearchFor(output As Worksheet)
Dim rowsCount As Long
Dim NCBead1 As Long, NCBead2 As Long, PCBead1 As Long, PCBead2 As Long
Dim IniString As String, IniVar As String
Dim rngCell As Range, rngCell2 As Range
Dim ArrCopy(1 To 9) As Variant
Dim LastRow As Long
Dim aCell As Range
LastRow = ActiveSheet.Range("B" & Rows.Count).End(xlUp).Row
'extract initial after last underscore
IniString = ActiveWorkbook.Sheets(1).Range("B6").Value
IniVar = Right(IniString, Len(IniString) - InStrRev(IniString, "_", , 1))
Debug.Print IniVar
'Debug.Print "LastRow = " & LastRow
Set aCell = ActiveSheet.Range("B1:B" & LastRow).Find(What:="Trimmed Mean", LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
'Debug.Print "Trimmed Mean can be found in Row # " & aCell.Row
'wb.Sheets(1).Select
For Each rngCell In ActiveSheet.Range("B" & aCell.Row & ":B" & LastRow)
If InStr(rngCell, "NC") > 0 Then
Debug.Print rngCell.Row
NCBead1 = rngCell.Offset(0, 1).Value
NCBead2 = rngCell.Offset(0, 2).Value
'End If
Exit For
End If
Next rngCell
For Each rngCell2 In ActiveSheet.Range("B" & aCell.Row & ":B" & LastRow)
If InStr(rngCell2, "PC") > 0 Then
Debug.Print rngCell2.Row
PCBead1 = rngCell2.Offset(0, 1).Value
PCBead2 = rngCell2.Offset(0, 2).Value
'End If
Exit For
End If
Next rngCell2
'Next searched
Debug.Print NCBead2
ArrCopy(1) = ActiveSheet.Range("B3").Value
ArrCopy(2) = IniVar
ArrCopy(3) = NCBead1
ArrCopy(4) = NCBead2
ArrCopy(5) = PCBead1
ArrCopy(6) = PCBead2
ArrCopy(7) = ActiveSheet.Range("B6").Value
ArrCopy(8) = NCBead1
ArrCopy(9) = NCBead1
' one row spanning several columns
Debug.Print "ArrCopy" & ArrCopy(1)
Debug.Print "ArrCopy" & ArrCopy(2)
Debug.Print "ArrCopy" & ArrCopy(3)
Dim Destination As Range
Set Destination = output.Range("A" & output.Range("A" & Rows.Count).End(xlUp).Row + 1)
Set Destination = Destination.Resize(1, UBound(ArrCopy))
Destination.Value = ArrCopy
End Function
Sub openselectedfiles()
Dim SaveDriveDir As String, MyPath As String, FnameInLoop As String
Dim mybook As Workbook, thisWb As Workbook
Dim N As Long, LstUnderSc As Long, ExtPer As Long, Varin As Long
Dim Fname As Variant, ArrCopy(1 To 9) As Variant
Dim output As Worksheet
Dim inLS2A As Boolean, inLS1PRA As Boolean, inLS1A As Boolean, inLSM12 As Boolean
Set thisWb = ThisWorkbook
' Save the current directory.
SaveDriveDir = CurDir
' Set the path to the folder that you want to open.
MyPath = Application.DefaultFilePath
' Change drive/directory to MyPath.
ChDrive MyPath
ChDir MyPath
' Open GetOpenFilename with the file filters.
Fname = Application.GetOpenFilename( _
FileFilter:="CSV Files (*.csv),*.csv", _
Title:="Select a file or files", _
MultiSelect:=True)
' Perform some action with the files you selected.
If IsArray(Fname) Then
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
For N = LBound(Fname) To UBound(Fname)
' Get only the file name and test to see if it is open.
FnameInLoop = Right(Fname(N), Len(Fname(N)) - InStrRev(Fname(N), Application.PathSeparator, , 1))
If bIsBookOpen(FnameInLoop) = False Then
Set mybook = Nothing
On Error Resume Next
Set mybook = Workbooks.Open(Fname(N))
On Error GoTo 0
If Not mybook Is Nothing Then
mybook.Sheets(1).Select
With ActiveSheet.Range("B11")
inLS2A = InStr(1, .Value, "LS2A", 1) > 0
inLS1PRA = InStr(1, .Value, "LS1PRA", 1) > 0
inLS1A = InStr(1, .Value, "LS1A", 1) > 0
inLSM12 = InStr(1, .Value, "LSM12", 1) > 0
End With
If inLS2A Then
Set output = thisWb.Sheets("SABII")
SearchFor output
ElseIf inLS1PRA Then
Set output = thisWb.Sheets("LPRI&II")
SearchFor output
ElseIf inLS1A Then
Set output = thisWb.Sheets("sabI")
SearchFor output
ElseIf inLSM12 Then
Set output = thisWb.Sheets("LSM")
SearchFor output
End If
'End If
mybook.Close SaveChanges:=False
Set mybook = Nothing
End If
Else
MsgBox "We skipped this file : " & Fname(N) & " because it is already open."
End If
Next N
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
End If
' Change drive/directory back to SaveDriveDir.
ChDrive SaveDriveDir
ChDir SaveDriveDir
End Sub
Function bIsBookOpen(ByRef szBookName As String) As Boolean
' Contributed by Rob Bovey
On Error Resume Next
bIsBookOpen = Not (Application.Workbooks(szBookName) Is Nothing)
End Function