Option Explicit
Sub trial()
Dim rng As Range
Dim celladdress As String
Dim myrange As Variant
Dim word As Variant
Set rng = Range("G3:G1000").Find(what:="Description")
rng.Find what:="Description"
celladdress = rng.Address
Dim max As Range
Dim b As Integer
b = Worksheets("Sheet1").Cells(Rows.count, "a").End(xlUp).Row
Set max = Range("G2", celladdress)
For Each word In max
If word = "Moisture Content" Then
Cells(b + 1, 24) = word.Offset(0, 1)
Exit For
End If
Next word
For Each word In max
If word = "Grading Class" Then
Cells(b + 1, 16) = word.Offset(0, 1)
Exit For
End If
Next word
For Each word In max
If word = "Zone X Constituent Parts" Then
Cells(b + 1, 17) = word.Offset(0, 1)
Exit For
End If
Next word
For Each word In max
If word = "Plastic Limit" Then
Cells(b + 1, 18) = word.Offset(0, 1)
Exit For
End If
Next word
For Each word In max
If word = "Liquid Limit" Then
Cells(b + 1, 19) = word.Offset(0, 1)
Exit For
End If
Next word
For Each word In max
If word = "Plasticity Index" Then
Cells(b + 1, 20) = word.Offset(0, 1)
Exit For
End If
Next word
Each word In max
If word = "Particle Density" Then
Cells(b + 1, 21) = word.Offset(0, 1)
Exit For
End If
Next word
For Each word In max
If word = "Optimum Moisture Content" Then
Cells(b + 1, 22) = word.Offset(0, 1)
Exit For
End If
Next word
For Each word In max
If word = "Maximum Dry Density" Then
Cells(b + 1, 23) = word.Offset(0, 1)
Exit For
End If
Next word
For Each word In max
If word = "Shear Strength at OMC" Then
Cells(b + 1, 15) = word.Offset(0, 1)
Exit For
End If
Next
Dim txt As String
Dim i As Integer
Dim reference As Variant
Dim k As Integer
Dim c As Integer
c = Worksheets("Sheet1").Cells(Rows.count, "a").End(xlUp).Row
txt = Cells(2, 5).Value
reference = Split(txt, " ")
For i = 0 To UBound(reference)
Cells(c + 1, 4).Value = reference(i)
next
txt = Cells(2, 5).Value
reference = Split(txt, " ")
For k = 0 To LBound(reference)
Cells(c + 1, 9).Value = reference(k)
Next k
Dim Last_Row As Long
Last_Row = Range("C3").End(xlDown).Offset(1).Row
Cells(Last_Row, [13]).Value = "Sampling"
Range("C3").Copy Range("C" & Last_Row)
Range("B3").Copy Range("B" & Last_Row)
Range("A3").Copy Range("A" & Last_Row)
Dim rnge As Range
Dim celladdres As String
Set rnge = Range("G3:G1000").Find(what:="Description")
rng.Find what:="Description"
celladdres = rnge.Address.Offset(-1, 50) - Invalid error
Dim maxy As Range
Set maxy = Range("G2", celladdress)
Worksheets("Sheet1").Range(max).Delete
End Sub
Hi i keep getting an invalid qualifer error and im unsure why. Im trying to get the find the next description and then offset the cell so i can delete all the information in the row above and 50 column along. im unsure why the error keep ocurring and what it actually means. any help would be greatly appreicated thanks max
Related
i'm trying to move words after the first space from 30th character in a string to the next row(i+1) added and remove those words moved to the next row from the current row(i). The code is giving Run-time error '5': Invalid procedure call or argument error message at Cells(i, 1).Value = Left(Cells(i, 1), InStr(30, Cells(i, 1), " ") - 1) line.
Sub TextLimit_02()
Dim i As Long
Dim CelLen As Long
For i = 1 To 50
CelLen = Len(Cells(i, 1))
If CelLen > 40 Then
Rows(i + 1).Insert
Cells(i + 1, 1).Value = Mid(Cells(i, 1), InStr(30, Cells(i, 1), " ") + 1, Len(Cells(i,
1).Value) - InStr(30, Cells(i, 1), " "))
Cells(i, 1).Value = Left(Cells(i, 1), InStr(30, Cells(i, 1), " ") - 1)
Else
End If
Next i
End Sub
Your code doesn't account for the possibility that in a string longer than 40, there are no spaces after position 30.
Breaking the logic down into steps makes it easy to detect this, and possibly add more code to deal with it
Sub TextLimit_02()
Dim i As Long
Dim CelLen As Long
Dim idx As Long
Dim CellString As String
Dim LeftPart As String
Dim RightPart As String
For i = 1 To 50
CellString = Cells(i, 1).Value2
CelLen = Len(CellString)
If CelLen > 40 Then
idx = InStr(30, CellString, " ")
If idx > 0 Then
Rows(i + 1).Insert
LeftPart = Left$(CellString, idx - 1)
RightPart = Mid$(CellString, idx + 1)
Cells(i, 1) = LeftPart
Cells(i + 1, 1) = RightPart
If idx > 40 Then
' there remains >40 characters in Cells(i, 1)
End If
Else
' No spaces after position 30. Cells(i, 1) remains longer than 40
End If
End If
Next i
End Sub
Note that if you split a lot of strings, your data may end up spanning past row 50. With For i = 1 to 50 you will miss processing some string in that case.
This code should do what you intend. Please test it and let me know what it does wrong.
Sub TextLimit_02()
' 269
Dim Txt As String ' text
Dim Tail As String ' tail end of Txt to be moved
Dim p As Long ' position of character in string
Dim R As Long ' loop counter: rows
Application.ScreenUpdating = False
' start from the end of column A to 2nd row
For R = Cells(Rows.Count, "A").End(xlUp).Row To 2 Step -1
Txt = Trim(Cells(R, "A").Value) ' remove leading/trailing blanks
p = InStr(Mid(Txt, 30), " ")
Tail = Trim(Mid(Txt, p + 30)) ' in case of double space
If Len(Tail) Then ' skip if no Tail
Cells(R, "A").Value = Left(Txt, p + 29)
Rows(R + 1).Insert
Cells(R + 1, "A").Value = Tail
End If
Next R
Application.ScreenUpdating = True
End Sub
Try this code:
Sub WrapText()
Const MIN_CARRY_POS = 30, MAX_LEN = 40, CARRY_SYMBOL = " " 'preferences
Dim cl As Range, txt As String, pos As Long, slice As Long
Application.ScreenUpdating = False
Set cl = ThisWorkbook.Worksheets(1).Range("A1")
Do 'main row loop
txt = RTrim(cl.Text)
Select Case Len(txt)
Case 0: Exit Do
Case Is > MAX_LEN
Do While Len(txt) > MAX_LEN 'a nested loop to process text that needs to be carried over
pos = InStr(MIN_CARRY_POS, txt, CARRY_SYMBOL)
If pos < 1 Then pos = MAX_LEN 'if no CARRY_SYMBOL after MIN_CARRY_POS then cut the string at MAX_LEN
slice = WorksheetFunction.Min(pos, MAX_LEN)
cl.Insert xlDown
cl.Offset(-1).Value = Mid(txt, 1, slice) 'output the head
txt = LTrim(Mid(txt, slice + 1)) 'get the rest of the txt
Loop
cl.Value = txt 'output the rest <= MAX_LEN
End Select
Set cl = cl.Offset(1) 'move to the next row
Loop
Application.ScreenUpdating = True
End Sub
Before
After
The macro is written to return the number of letter differences (insertions, replacements, or deletions) of two words (case sensitive).
It is suppose to format and output in phrases
1-2 Letters off,
1-2 Letters off, Same Starting Letter,
3-4 Letters off,
3-4 Letters off, Same Starting Letter and
5 or more letters off, CHECK
It is only outputting
1-2 Letters off, Same Starting Letter,
3-4 Letters off, Same Starting Letter and
5 or more Letters off, CHECK
I would like the formatting to stay the same for now.
Sub Test_HW_Formatter()
'declare the variables
Dim i As Integer
Dim j As Integer
Dim k As Integer
Dim testNames As Integer
Dim responses As Integer
Dim printRow As Integer
Dim name As String
Dim count As Integer
Dim coding As String
Dim statLetter As Boolean
Dim tempCount As Integer
Dim tempResp As String
'the queues for the entries, the respective counts, and respective codes
Dim words As Object
Set words = CreateObject("System.Collections.Queue")
Dim counts As Object
Set counts = CreateObject("System.Collections.Queue")
Dim codes As Object
Set codes = CreateObject("System.Collections.Queue")
'set the variables
printRow = 3
testNames = Selection.Columns.count
responses = Selection.Rows.count - 1
Cells(4, 3).Value = Selection(4)
startLetter = True
'make the header
Cells(1, 1).Value = "Name"
Cells(1, 2).Value = "Response"
Cells(1, 3).Value = "Count"
Cells(1, 4).Value = "Code"
Cells(1, 5).Value = "Agency close matches"
Cells(1, 6).Value = "N=" + Trim(Str(responses))
Cells(1, 6).Interior.Color = RGB(255, 255, 204)
Cells(1, 6).HorizontalAlignment = xlCenter
For i = 1 To 5
Cells(1, i).Interior.Color = RGB(1, 139, 175)
Cells(1, i).Font.Color = RGB(255, 255, 255)
Cells(1, i).HorizontalAlignment = xlCenter
Next i
'get the information and put it in the queues
For i = 0 To (testNames - 1)
name = Selection(i + 1).Value
For j = 1 To responses
count = 1
If Not Selection(j * testNames + i + 1) = "" Then
For k = 1 To (responses - j)
If Not Selection((j + k) * testNames + i + 1).Value = "" Then
If Trim(UCase(Selection(j * testNames + i + 1).Value)) = Trim(UCase(Selection((j + k) * testNames + i + 1).Value)) Then
count = count + 1
Selection((j + k) * testNames + i + 1).Value = ""
End If
End If
Next k
'get the coding
coding = ""
ld = Levenshtein(name, Trim(UCase(Selection(j * testNames + i + 1))))
If Mid(testName, 1, 1) = Mid(sample, 1, 1) Then
startLetter = True
Else
startLetter = False
End If 'if for starting letter
Select Case ld
Case 0
coding = "Exact Match"
Case 1
If startLetter = True Then
coding = "1-2 Letters off, Same Starting Letter"
Else
coding = "1-2 Letters off"
End If
Case 2
If startLetter = True Then
coding = "1-2 Letters off, Same Starting Letter"
Else
coding = "1-2 Letters off"
End If
Case 3
If startLetter = True Then
coding = "3-4 Letters off, Same Starting Letter"
Else
coding = "3-4 Letters off"
End If
Case 4
If startLetter = True Then
coding = "3-4 Letters off, Same Starting Letter"
Else
coding = "3-4 Letters off"
End If
Case Else
coding = "5 or more Letters off, CHECK"
End Select
'enqueue the values
tempResp = UCase(Mid(Selection(j * testNames + i + 1).Value, 1, 1)) + LCase(Mid(Selection(j * testNames + i + 1).Value, 2, Len(Selection(j * testNames + i + 1).Value)))
words.enqueue (tempResp)
counts.enqueue (count)
codes.enqueue (coding)
End If 'if the cell is not blank
Next j
'print the queues from the ith column
'start the section header
Cells(printRow, 1).Value = name
Cells(printRow, 1).Font.Color = RGB(255, 255, 255)
For k = 1 To 5
Cells(printRow, k).Interior.Color = RGB(1, 139, 175)
Cells(printRow, k).HorizontalAlignment = xlCenter
Next k
tempCount = counts.count
Cells(150, 20 + i).Value = tempCount
For k = 1 To tempCount
Cells(printRow + k, 2).Value = words.dequeue
Cells(printRow + k, 3).Value = counts.dequeue
Cells(printRow + k, 4).Value = codes.dequeue
If Cells(printRow + k, 4).Value = "Exact Match" Then
Cells(printRow + k, 4).Interior.Color = RGB(236, 239, 218)
End If
Next k
printRow = printRow + tempCount + 2
Next i
End Sub
Edited to add counting replicates of the same name, and skip empty values:
Sub Test_HW_Formatter()
Dim arr, numReps As Long, ws As Worksheet, col As Long, c As Range
Dim nm As String, rep As Long, cmp As String
Dim i As Long, dict As Object, tmp
arr = Selection.Value 'inputs
numReps = UBound(arr, 1) - 1 'reps per column
Set ws = Selection.Parent 'sheet with selection
With ws.Range("A1:E1")
.Value = Array("Name", "Response", "Count", "Code", "Agency Close match")
doHeaders .Cells
End With
ws.Range("F1").Value = "N=" & numReps
Set c = ws.Range("A3") 'start of output sections
For col = 1 To UBound(arr, 2) 'loop columns of selection
nm = arr(1, col)
c.Value = nm
doHeaders c.Resize(1, 5) 'format headers
i = 0
Set dict = CreateObject("scripting.dictionary")
For rep = 1 To numReps 'loop values to compare
cmp = arr(rep + 1, col)
If Len(cmp) > 0 Then
If Not dict.exists(cmp) Then
i = i + 1
dict.Add cmp, i
c.Offset(i, 1).Value = cmp
c.Offset(i, 2) = 1
c.Offset(i, 3).Value = MatchCoding(nm, cmp) 'now in separate function
Else
'increment count for existing line
c.Offset(dict(cmp), 2).Value = c.Offset(dict(cmp), 2).Value + 1
End If
End If 'not zero-length
Next rep
Set c = c.Offset(i + 2, 0) 'next set
Next col
End Sub
'return a string summarizing how closeley two terms match
Function MatchCoding(nm As String, cmp As String)
Dim ld As Long, firstMatch As Boolean
firstMatch = (Left(nm, 1) = Left(cmp, 1))
ld = Levenshtein(nm, cmp)
Select Case ld
Case 0: MatchCoding = "Exact Match"
Case 1, 2: MatchCoding = "1-2 Letters off"
Case 3, 4: MatchCoding = "3-4 Letters off"
Case Else: MatchCoding = "5 or more Letters off, CHECK"
End Select
If ld > 0 And ld < 5 Then MatchCoding = MatchCoding & _
IIf(firstMatch, ", Same Starting Letter", "")
End Function
'utility sub for formatting headers
Sub doHeaders(rng As Range)
With rng
.Interior.Color = RGB(1, 139, 175)
.Font.Color = RGB(255, 255, 255)
.HorizontalAlignment = xlCenter
End With
End Sub
The below code is not showing the results on the "All Stock Analysis" sheet.
I tried doing a test after the activation of each worksheet (Range("I1).Interior.Color = vbGreen) and cell I1 turns green on each of the desired worksheets. What other tests can I try? No error msg pops up.
Sub AllStocksAnalysisRefactored()
Dim startTime As Single
Dim endTime As Single
yearValue = InputBox("What year would you like to run the analysis on?")
startTime = Timer
'Format the output sheet on All Stocks Analysis worksheet
Worksheets("All Stock Analysis").Activate
Range("A1").Value = "All Stocks (" + yearValue + ")"
'Create a header row
Cells(3, 1).Value = "Ticker"
Cells(3, 2).Value = "Total Daily Volume"
Cells(3, 3).Value = "Return"
'Initialize array of all tickers
Dim tickers(12) As String
tickers(0) = "AY"
tickers(1) = "CSIQ"
tickers(2) = "DQ"
tickers(3) = "ENPH"
tickers(4) = "FSLR"
tickers(5) = "HASI"
tickers(6) = "JKS"
tickers(7) = "RUN"
tickers(8) = "SEDG"
tickers(9) = "SPWR"
tickers(10) = "TERP"
tickers(11) = "VSLR"
'Activate data worksheet
Worksheets(yearValue).Activate
'Get the number of rows to loop over
RowCount = Cells(Rows.Count, "A").End(xlUp).Row
'1a) Create a ticker Index
Dim tickerIndex As Single
tickerIndex = 0
'1b) Create three output arrays
Dim tickerVolumes(12) As LongLong
Dim tickerstartingPrices(12) As Single
Dim tickerendingPrices(12) As Single
''2a) Create a for loop to initialize the tickerVolumes to zero.
For i = 0 To 11
tickerVolumes(i) = 0
''2b) Loop over all the rows in the spreadsheet.
For j = 2 To RowCount
'3a) Increase volume for current ticker
tickerVolumes(tickerIndex) = tickerVolumes(tickerIndex) + Cells(j, 8).Value
'3b) Check if the current row is the first row with the selected tickerIndex.
'If Then
If Cells(j - 1, 1).Value <> tickers(tickerIndex) And _
Cells(j, 1).Value = tickers(tickerIndex) Then
tickerstartingPrices(tickerIndex) = Cells(j, 6).Value
'End If
End If
'3c) check if the current row is the last row with the selected ticker
'If the next row’s ticker doesn’t match, increase the tickerIndex.
'If Then
If Cells(j + 1, 1).Value <> tickers(tickerIndex) And _
Cells(j, 1).Value = tickers(tickerIndex) Then
tickerendingPrices(tickerIndex) = Cells(j, 6).Value
'3d Increase the tickerIndex.
tickerIndex = tickerIndex + 1
'End If
End If
Next j
Next i
'4) Loop through your arrays to output the Ticker, Total Daily Volume, and Return.
For i = 0 To 11
Worksheets("All Stock Analysis").Activate
Next i
'Formatting
Worksheets("All Stock Analysis").Activate
Range("A3:C3").Font.FontStyle = "Bold"
Range("A3:C3").Borders(xlEdgeBottom).LineStyle = xlContinuous
Range("B4:B15").NumberFormat = "#,##0"
Range("C4:C15").NumberFormat = "0.0%"
Columns("B").AutoFit
dataRowStart = 4
dataRowEnd = 15
For i = dataRowStart To dataRowEnd
If Cells(i, 3) > 0 Then
Cells(i, 3).Interior.Color = vbGreen
Else
Cells(i, 3).Interior.Color = vbRed
End If
Next i
endTime = Timer
MsgBox "This code ran in " & (endTime - startTime) & _
" seconds for the year " & (yearValue)
End Sub
Here is how "All Stock Analysis" sheet will look after running the code:
You only need to scan the data sheet once if you use a dictionary object to convert the ticker ID to an array index number.
Option Explicit
Sub AllStocksAnalysisRefactored()
Const SHT_NAME = "All Stock Analysis"
Dim wb As Workbook, ws As Worksheet, wsYr As Worksheet
Dim cell As Range, yr As String, iRow As Long, iLastRow As Long
Dim t As Single: t = Timer
' choose data worksheet
yr = InputBox("What year would you like to run the analysis on ? ", "Enter Year", Year(Date))
Set wb = ThisWorkbook
On Error Resume Next
Set wsYr = wb.Sheets(yr)
On Error GoTo 0
' check if exists
If wsYr Is Nothing Then
MsgBox "Sheet '" & yr & "' does not exists.", vbCritical, "Error"
Exit Sub
End If
'Initialize array of all tickers
Dim tickerID, tickerData(), i As Integer, n As Integer
Dim dict As Object, sId As String
tickerID = Array("AY", "CSIQ", "DQ", "ENPH", "FSLR", "HASI", _
"JKS", "RUN", "SEDG", "SPWR", "TERP", "VSLR")
n = UBound(tickerID) + 1
ReDim tickerData(1 To n, 1 To 5)
' create dict id to index
Set dict = CreateObject("Scripting.Dictionary")
For i = 1 To n
sId = UCase(Trim(tickerID(i - 1)))
tickerData(i, 1) = sId ' id
tickerData(i, 2) = 0 ' volume
tickerData(i, 3) = 0 ' start price
tickerData(i, 4) = 0 ' finish price
tickerData(i, 5) = 0 ' count
dict.Add sId, i
Next
'Get the number of rows to loop over
iLastRow = wsYr.Cells(Rows.Count, "A").End(xlUp).Row
' Loop over all the rows in the spreadsheet.
' A=ticker, F=Price , H=Volume
For iRow = 2 To iLastRow
sId = UCase(Trim(wsYr.Cells(iRow, "A")))
If dict.exists(sId) Then
i = dict(sId)
' volume
tickerData(i, 2) = tickerData(i, 2) + wsYr.Cells(iRow, "H") ' volume
' start price when count is 0
If tickerData(i, 5) = 0 Then
tickerData(i, 3) = wsYr.Cells(iRow, "F")
End If
' end price
tickerData(i, 4) = wsYr.Cells(iRow, "F")
' count
tickerData(i, 5) = tickerData(i, 5) + 1
End If
Next
'Format the output sheet on All Stocks Analysis worksheet
Set ws = wb.Sheets(SHT_NAME)
ws.Cells.Clear
With ws
.Range("A1").Value2 = "All Stocks (" & yr & ")"
With .Range("A3:E3")
.Value2 = Array("Ticker", "Total Daily Volume", "Start Price", "End Price", "Return")
.Font.FontStyle = "Bold"
.Borders(xlEdgeBottom).LineStyle = xlContinuous
End With
.Range("A4").Resize(n, 4).Value2 = tickerData
.Range("B4:D4").Resize(n).NumberFormat = "#,##0"
.Range("E4").Resize(n).NumberFormat = "0.0%"
.Columns("B").AutoFit
End With
' coloring
For Each cell In ws.Range("E4").Resize(n)
cell.FormulaR1C1 = "=(RC[-1]-RC[-2])/RC[-2]" ' end-start/start
If cell > 0 Then
cell.Interior.Color = vbGreen
Else
cell.Interior.Color = vbRed
End If
Next
ws.Activate
ws.Range("A1").Select
MsgBox "This code ran for (" & yr & ")", vbInformation, Int(Timer - t) & " seconds"
End Sub
I'm doing spell check in a range by using the below code..
Sub SpellCheck()
Application.SpellingOptions.DictLang = 1033
Dim cel As Range, CellLen As Long, CurChr As Long, TheString As String
Dim a As Integer
For Each cel In Range("Spell[description]")
'splitting paragraph into words
For CurChr = 1 To Len(cel.Value)
If Asc(Mid(cel.Value, CurChr, 1)) = 32 Then
If InStr(CurChr + 1, cel.Value, " ") = 0 Then
TheString = Mid(cel.Value, CurChr + 1, Len(cel.Value) - CurChr)
Else
TheString = Mid(cel.Value, CurChr + 1, InStr(CurChr + 1, cel.Value, " ") - CurChr)
End If
'checking spell as per words
If Not Application.CheckSpelling(Word:=TheString) Then
cel.Characters(CurChr + 1, Len(TheString)).Font.Color = RGB(255, 0, 0)
'updating the error words in the next sheet
Sheets(2).Activate
a = Cells(Rows.Count, 1).End(xlUp).Row
Cells(a + 1, 1).Value = cel.Offset(0, -1).Value
Cells(a + 1, 2).Value = TheString
Else
cel.Characters(CurChr + 1, Len(TheString)).Font.Color = RGB(0, 0, 0)
End If
TheString = ""
End If
Next CurChr
Next cel
End Sub
It will highlight the error words in red and update them along with its ID and error word in sheet2. However i need to update the suggested values provided for the error by excel in the next cell (after error words in sheet2).
I'm completely new to this spell check in VBA, can anyone help me out..!
I have written some code that reads a spreadsheet that is filled with procedures that will be carried out by workers and divides them into "shifts" based on the duration of each activity so that preparation for certain steps can be made before.
I am looking for some help, as if someone inputs text that is not an integer (a note or something) into the "duration" tab, (which is stored as "X" in this code) the macro stops prematurely.
I was thinking I could use an if statement to check this, perhaps the "IsNumeric()" function, but it would not run and I knew I was not doing it correctly.
Private Sub CommandButton1_Click()
'define variables
Dim duration As Integer, n As Long, i As Integer, x As Integer, m As Long
Dim toolRange As Range, partRange As Range, perRange As Range, workRange As Range, ppeRange As Range
n = 3 'indicates row
m = 3 'concatenation counter
duration = 0 'duration counter
x = 0 'duration placeholder
For i = 1 To 100 'Assumed max 50 shifts (This can be changed or solved with more code, but should be set higher than predicted # of shifts)
duration = 0 'resets duration for next count
While duration < Worksheets("Shifts").Cells(6, "K").Value 'shift length can be altered
x = Worksheets("SR060-SR070").Cells(n, "F").Value
duration = duration + x 'adds duration until it is over 320
n = n + 1
Wend
With Worksheets("SR060-SR070")
Set toolRange = .Range(.Cells(m, "H"), .Cells(n, "H")) 'creates tool range
End With
With Worksheets("SR060-SR070")
Set partRange = .Range(.Cells(m, "I"), .Cells(n, "I")) 'creates part range
End With
With Worksheets("SR060-SR070")
Set perRange = .Range(.Cells(m, "E"), .Cells(n, "E")) 'creates per range
End With
With Worksheets("SR060-SR070")
Set workRange = .Range(.Cells(m, "P"), .Cells(n, "P")) 'creates permit range
End With
With Worksheets("SR060-SR070")
Set ppeRange = .Range(.Cells(m, "Q"), .Cells(n, "Q")) 'creates ppe range
End With
Worksheets("Shifts").Cells(i + 1, 1).Value = i 'creates shift
Worksheets("Shifts").Cells(i + 1, 2).Value = Application.Max(perRange) 'creates max per
Worksheets("Shifts").Cells(i + 1, 3).Value = duration 'creates duration
'Worksheets("Shifts").Cells(i + 1, 4).Value = ConcatenateAllCellValuesInRange(toolRange) 'inputs tools
Worksheets("Shifts").Cells(i + 1, 4).Value = ConcatUniq(toolRange, " ") 'inputs tools
'Worksheets("Shifts").Cells(i + 1, 5).Value = ConcatenateAllCellValuesInRange(partRange) 'inputs parts
Worksheets("Shifts").Cells(i + 1, 5).Value = ConcatUniq(partRange, " ") 'inputs parts
'Worksheets("Shifts").Cells(i + 1, 6).Value = ConcatenateAllCellValuesInRange(workRange) 'inputs permits
Worksheets("Shifts").Cells(i + 1, 6).Value = ConcatUniq(workRange, " ") 'inputs permits
'Worksheets("Shifts").Cells(i + 1, 7).Value = ConcatenateAllCellValuesInRange(ppeRange) 'inputs ppe
Worksheets("Shifts").Cells(i + 1, 7).Value = ConcatUniq(ppeRange, " ") 'inputs ppe
m = n 'Allows it to segement down page
Next i 'goes to next shift
End Sub
'Concatenate function
Function ConcatUniq(ByRef rng As Range, _
ByVal myJoin As String) As String
Dim r As Range
Static dic As Object
If dic Is Nothing Then _
Set dic = CreateObject("Scripting.Dictionary")
For Each r In rng
dic(r.Value) = Empty
Next
ConcatUniq = Join$(dic.keys, myJoin)
dic.RemoveAll
End Function
You could use the Val function to get the numeric part of a string. Val will also return 0 if the value is not numeric or empty string. You could combine this with IsNumeric in your While condition.
Dim vVal As Variant
Dim nVal As Long
vVal = Worksheets("Shifts").Cells(6, "K").Value
nVal = Val(vVal)
While duration < nVal && IsNumeric(vVal)
...
Wend
References:
Val Function - VBA
IsNumeric Function - VBA