What is Function/Class Module to read all the headers from collection? - excel

I have a set of collections to read into a collection.
Defining all of the columns is troublesome & the columns will grow in the future.
Below is the sample code in which I need to define all the columns in a class module first, then I can use the columns in a module.
Class modules:
Option Explicit
Public COL_ID As Integer
Public PCT_GRTHAN As Double
Public PCT_LESSTHAN_EQUAL As Double
Public TIME_BUCKET As String
Public NO_OF_GROUPS As Integer
Public sum As Integer
Public PCT As Double
My code:
Sub UtilProfReport()
Dim sh As Worksheet
Dim row As Long
Dim col3 As New Collection
Dim rg As Range
Set rg = Sheets("Sheet1").Range("A1").CurrentRegion
Dim i As Long, UtilProf As clsUtil
For i = 2 To rg.rows.Count
If rg.Cells(i, 1).value > 0 Or i = 1 Then
Set UtilProf = New clsUtil
UtilProf.COL_ID = rg.Cells(i, 1).value
UtilProf.PCT_GRTHAN = rg.Cells(i, 2).value
UtilProf.PCT_LESSTHAN_EQUAL = rg.Cells(i, 3).value
UtilProf.TIME_BUCKET = rg.Cells(i, 4).value
UtilProf.NO_OF_GROUPS = rg.Cells(i, 5).value
UtilProf.sum = rg.Cells(i, 6).value
UtilProf.PCT = rg.Cells(i, 7).value
col3.Add UtilProf
End If
Next i
Worksheets.Add
Set sh = ActiveSheet
sh.Range("A1").value = "UTIL"
sh.Range("A2").value = ">"
sh.Range("B2").value = ChrW(&H2264)
sh.Range("C2").value = "# Groups"
sh.Range("D2").value = "%"
ActiveWindow.DisplayZeros = False
sh.DisplayPageBreaks = False
With Application
.ScreenUpdating = False
.EnableAnimations = False
End With
With sh.Range("A1:D1")
.HorizontalAlignment = xlLeft
.VerticalAlignment = xlBottom
.WrapText = False
.Orientation = 0
.AddIndent = False
.IndentLevel = 0
.ShrinkToFit = False
.ReadingOrder = xlContext
.MergeCells = True
.Interior.Color = 15849925
End With
sh.Range("A2:D2").Interior.Color = 14277081
Dim UtilProfout As clsUtil
For i = 1 To col3.Count
row = i + 2
With sh
Set UtilProfout = col3(i)
.Cells(row, 1).value = UtilProfout.PCT_GRTHAN
.Cells(row, 2).value = UtilProfout.PCT_LESSTHAN_EQUAL
.Cells(row, 3).value = UtilProfout.NO_OF_GROUPS
.Cells(row, 4).value = UtilProfout.PCT
End With
Next i
End Sub
Below is idea output
How to write user defined function/class module to load the raw data in excel worksheet so that I do not need to dim every header for the sheet?
I expect the class module/ function to not only be used for this raw data, expecting the class module/function can be used to load other worksheets in same workbook.
Foe example, for the class module I can use the readfile function.

It's not possible to loop through the class module variables in VBA. You can use an array instead of a class module:
For i = 1 To rg.Rows.Count
' Add current row as array
coll.Add rg.Rows(i).Value
Next i
You can retrieve it like this:
Dim arr As Variant
' Get array at position 1
arr = coll(1)
You can write it to the worksheet like this:
Dim j As Long, arr As Variant
For i = 1 To coll3.Count
arr = coll3(i)
For j = 1 To UBound(arr, 2)
.Cells(Row, j).Value = arr(1, j)
Next j
Next i

Related

Autofit won't run as part of a sub

I'm working on a sub where, after doing a whole bunch of other things, it just selects all the cells in the active sheet and sets the rows to auto-fit height. For some reason it won't work! I've tried to the autofit row height command in various different places, but it seems that so long as it's part of the larger sub, or called within it, it won't work. However, if I write a separate sub that is run separately, it will work just fine. Does anyone know why this could be?
Below is the sub where it's misbehaving, plus the other sub I made that I can run separately. Any suggestions on how to make this all more efficient is also very welcome! (I also kind of learned coding in the wild, so I don't really know best practices...)
Option Explicit
Sub WriteToIndex(ByRef rowsArray() As Variant, ByRef Indexes() As Integer, ByRef HeaderNames() As String, myTable As ListObject, sheetName As String)
Debug.Print sheetName
Sheets(sheetName).Activate
Dim i, j As Variant
Dim count As Integer
'If no rows, no write
If (Not Not rowsArray) <> 0 Then
Else:
'If the index is longer than 5000 rows, this will need to be updated!
Range("B4:L5000").Clear
MsgBox "Sheet " & sheetName & " was not populated because there is nothing attributed to it"
Exit Sub
End If
'If nothing in Int/Ext section, no write
count = 0
For i = LBound(rowsArray) To UBound(rowsArray)
For j = LBound(Indexes) To UBound(Indexes)
If myTable.DataBodyRange(rowsArray(i), Indexes(j)).Value = "n" Then count = count + 1
Next
Next
If count = 0 Then
'If the index is longer than 5000 rows, this will need to be updated!
Range("B4:L5000").Clear
MsgBox "Sheet " & sheetName & " was not populated because there is nothing attributed to it"
Exit Sub
End If
Sheets(sheetName).Activate
'Pulls desired index fonts and sizes from Settings tab
Dim IndexFont As String, HeaderFSize, BodyFSize As Integer, HeaderBold As Boolean
IndexFont = Worksheets("Settings").Cells(10, 11).Value
HeaderFSize = Worksheets("Settings").Cells(11, 11).Value
HeaderBold = Worksheets("Settings").Cells(12, 11).Value
BodyFSize = Worksheets("Settings").Cells(13, 11).Value
'Remove headers from array if there are no items for the index
Dim loopno, pos, zeroloops(), zeroloopstart As Integer
count = 0
zeroloopstart = 0
loopno = 1
ReDim Preserve zeroloops(zeroloopstart)
For i = LBound(Indexes) To UBound(Indexes)
For j = LBound(rowsArray) To UBound(rowsArray)
If myTable.DataBodyRange(rowsArray(j), Indexes(i)).Text = "n" Then count = count + 1
Next
If count = 0 Then
pos = loopno - 1
ReDim Preserve zeroloops(0 To zeroloopstart)
zeroloops(zeroloopstart) = pos
zeroloopstart = zeroloopstart + 1
End If
count = 0
loopno = loopno + 1
Next
'If a header is in the zeroloops array, it gets removed from the Header array
If IsEmpty(zeroloops(0)) Then
Debug.Print "Empty"
Else
For i = LBound(zeroloops) To UBound(zeroloops)
For j = zeroloops(i) To UBound(Indexes) - 1
Indexes(j) = Indexes(j + 1)
Next j
For j = zeroloops(i) To UBound(HeaderNames) - 1
HeaderNames(j) = HeaderNames(j + 1)
Next j
For j = LBound(zeroloops) To UBound(zeroloops)
zeroloops(j) = zeroloops(j) - 1
Next j
Debug.Print
ReDim Preserve Indexes(0 To (UBound(Indexes) - 1))
ReDim Preserve HeaderNames(0 To (UBound(HeaderNames) - 1))
Next i
End If
'If the index is longer than 5000 rows, this will need to be updated!
Range("B4:L5000").Clear
'Apply preferred font to entire sheet
Cells.Font.Name = IndexFont
Dim KeyIDCol, DescCol, SourceCol, ProductCol, CatCol, ColorCol, FinishCol, SizeCol, ContactCol, SpecCol, RemarkCol As Integer
'Index for each value to report
'If additional column needs to be reported, add the line and swap out the name in the Listcolumns definition
KeyIDCol = Worksheets("Database").ListObjects("Database").ListColumns("KEYNOTE #").Index
DescCol = Worksheets("Database").ListObjects("Database").ListColumns("KEYNOTE DESCRIPTION").Index
SourceCol = Worksheets("Database").ListObjects("Database").ListColumns("SOURCE").Index
ProductCol = Worksheets("Database").ListObjects("Database").ListColumns("PRODUCT").Index
CatCol = Worksheets("Database").ListObjects("Database").ListColumns("CAT. NO.").Index
ColorCol = Worksheets("Database").ListObjects("Database").ListColumns("COLOR").Index
FinishCol = Worksheets("Database").ListObjects("Database").ListColumns("FINISH").Index
SizeCol = Worksheets("Database").ListObjects("Database").ListColumns("SIZE").Index
ContactCol = Worksheets("Database").ListObjects("Database").ListColumns("CONTACT").Index
SpecCol = Worksheets("Database").ListObjects("Database").ListColumns("SECTION #").Index
RemarkCol = Worksheets("Database").ListObjects("Database").ListColumns("REMARKS").Index
'Definitions for write loop
Dim NextWriteRow, HeaderListIndex As Integer
Dim ArrayItem As Variant
Dim WriteStartCell, Cell As Range
NextWriteRow = 4
HeaderListIndex = 0
i = 1 ' for moving to the next KeyID
j = 0 ' start counter for steps
Set WriteStartCell = Cells(NextWriteRow, 2)
Dim k As Variant
'Outer loop puts in headers
For Each ArrayItem In Indexes
With Cells(NextWriteRow, 2)
.Value = HeaderNames(HeaderListIndex)
.VerticalAlignment = xlBottom
.Font.Size = HeaderFSize
.Font.Bold = HeaderBold
End With
HeaderListIndex = HeaderListIndex + 1
'Second loop puts in KeynoteID with all pertinent info
For k = LBound(rowsArray) To UBound(rowsArray)
If myTable.DataBodyRange(rowsArray(k), ArrayItem).Value = "n" Then
With WriteStartCell
.Offset(i, 0).Value = myTable.DataBodyRange(rowsArray(k), ArrayItem).Offset(, KeyIDCol - ArrayItem).Value
.Offset(i, 1).Value = myTable.DataBodyRange(rowsArray(k), ArrayItem).Offset(, DescCol - ArrayItem).Value
.Offset(i, 2).Value = myTable.DataBodyRange(rowsArray(k), ArrayItem).Offset(, SourceCol - ArrayItem).Value
.Offset(i, 3).Value = myTable.DataBodyRange(rowsArray(k), ArrayItem).Offset(, ProductCol - ArrayItem).Value
.Offset(i, 4).Value = myTable.DataBodyRange(rowsArray(k), ArrayItem).Offset(, CatCol - ArrayItem).Value
.Offset(i, 5).Value = myTable.DataBodyRange(rowsArray(k), ArrayItem).Offset(, ColorCol - ArrayItem).Value
.Offset(i, 6).Value = myTable.DataBodyRange(rowsArray(k), ArrayItem).Offset(, FinishCol - ArrayItem).Value
.Offset(i, 7).Value = myTable.DataBodyRange(rowsArray(k), ArrayItem).Offset(, SizeCol - ArrayItem).Value
.Offset(i, 8).Value = myTable.DataBodyRange(rowsArray(k), ArrayItem).Offset(, ContactCol - ArrayItem).Value
With .Offset(i, 9)
.NumberFormat = "000000"
.HorizontalAlignment = xlCenter
.Value = myTable.DataBodyRange(rowsArray(k), ArrayItem).Offset(, SpecCol - ArrayItem).Value
End With
.Offset(i, 10).Value = myTable.DataBodyRange(rowsArray(k), ArrayItem).Offset(, RemarkCol - ArrayItem).Value
End With
With Range(WriteStartCell.Offset(i, 0), WriteStartCell.Offset(i, 10))
.VerticalAlignment = xlTop
.WrapText = True
.Borders(xlDiagonalDown).LineStyle = xlNone
.Borders(xlDiagonalUp).LineStyle = xlNone
.Font.Size = BodyFSize
With .Borders
.LineStyle = xlContinuous
.ColorIndex = xlAutomatic
.TintAndShade = 0
.Weight = xlThin
End With
End With
i = i + 1
j = j + 1
End If
Next
j = j + 2
NextWriteRow = NextWriteRow + j
i = i + 2
j = 0
Next
'This is the autofit that won't work for some reason
Cells.Rows.Autofit
Debug.Print "Works"
End Sub
'---
Sub AutofitRowHeight()
Dim sheetnames() As String
ReDim sheetnames(0 To 17)
sheetnames(0) = "SF-ALL-I"
sheetnames(1) = "SF-ALL-E"
sheetnames(2) = "SF-H-I"
sheetnames(3) = "SF-H-E"
sheetnames(4) = "SF-CUP-I"
sheetnames(5) = "SF-CUP-E"
sheetnames(6) = "SF-GB-I"
sheetnames(7) = "SF-GB-E"
sheetnames(8) = "LM-ALL-I"
sheetnames(9) = "LM-ALL-E"
sheetnames(10) = "LM-H-I"
sheetnames(11) = "LM-H-E"
sheetnames(12) = "LM-CC-I"
sheetnames(13) = "LM-CC-E"
sheetnames(14) = "LM-SCC-I"
sheetnames(15) = "LM-SCC-E"
sheetnames(16) = "LM-GB-I"
sheetnames(17) = "LM-GB-E"
Dim i As Variant
For i = LBound(sheetnames) To UBound(sheetnames)
Sheets(sheetnames(i)).Activate
Cells.Rows.AutoFit
Next
Sheets("Database").Activate
Cells(1, 1).Select
End Sub

Object doesn't support this property or method when I try to run countif based on activex textbox

I am relatively new to this coding. I am trying to add to my inventory database(in another sheet) if the model that is key into the activex textbox dose not match. If it matches, then it will automatically update to the quantity. However, I am getting error438. Here is the code that I have written so far.
Sub Add()
Dim invdata As Worksheet
Dim frm As Worksheet
Dim iqty As Integer
Set frm = ThisWorkbook.Sheets("UserForm")
Set invdata = ThisWorkbook.Sheets("Inventory Database")
iqty = frm.Range("B9")
Dim irow As Integer
Dim jrow As Integer
Dim i As Integer
If Application.WorksheetFunction.CountIf(invdata.Range("C:C"), ActiveSheet.tbModel.Value) > 0 Then
jrow = invdata.Range("A" & invdata.Rows.Count).End(xlUp).row + 1
With invdata
.Cells(jrow, 1).Value = frm.Range("B6").Value
.Cells(jrow, 2).Value = frm.Range("B7").Value
.Cells(jrow, 3).Value = ActiveSheet.tbModel.Value
.Cells(jrow, 4).Value = frm.Range("B9").Value
End With
MsgBox ("New Model Added!")
Else
irow = invdata.Cells(Rows.Count, 3).End(xlUp).row
For i = 2 To irow
If Sheet1.Cells(i, 3) = ActiveSheet.tbModel.Value Then
Sheet1.Cells(i, 4) = Sheet1.Cells(i, 4) + iqty
Exit Sub
End If
Next i
End If
End Sub
Try this - using Find() instead of CountIf() saves you from the loop:
Sub Add()
Dim invdata As Worksheet, frm As Worksheet, model, f As Range
Dim iqty As Long
Set frm = ThisWorkbook.Sheets("UserForm")
Set invdata = ThisWorkbook.Sheets("Inventory Database")
iqty = frm.Range("B9").Value
model = frm.OLEObjects("tbModel").Object.Value '####
'see if there's a match using `Find()`
Set f = invdata.Range("C:C").Find(what:=model, lookat:=xlWhole)
If f Is Nothing Then
'model was not found in Col C
With invdata.Range("A" & invdata.Rows.Count).End(xlUp).Offset(1)
.Value = frm.Range("B6").Value
.Offset(0, 1).Value = frm.Range("B7").Value
.Offset(0, 2).Value = model
.Offset(0, 3).Value = iqty
End With
MsgBox "New Model Added!"
Else
With f.EntireRow.Cells(4)
.Value = .Value + iqty ' update qty in row `m`
End With
End If
End Sub

superscript letters in vba string variable

I am looking for how to super/subscript a letter/digit in a VBA string variable. I am working in excel with charts that have axes, titles and chart titles that require s-scripting. Additionally, there is a formula to go in a textbox:
Cpt = Cp0 * e^(-ket) where all the p's, t's and 0 are subscripts. The entire expression, (-ket) is superscripted with embedded subscripting for the e (the e between the k & t). Finally, all the specially formatted string variables will be copied to PowerPoint variables via clipboard/gettext.
Any help / guidance is greatly appreciated.
Pat K.
It is workaround Idea only and the code may not be useful for your purpose depending on source and destination of the data and may be treated as demo only. i have only used excel cells and Text Boxes on a sheet as destination and used PowerPoint Text Boxes as target.
The simple approach is that while picking up String from formatted cells/Text Boxes from excel to a variable, Font Subscript, Superscript information is also to be picked up in a parallel variable (here in a 2D Array). The same font information may be used while writing in PowerPoint. The demo idea have to be Modified/Converted to suit your need.
Demo Screen shot
The demo code
Sub Sscript()
Dim CellStr() As Variant
Dim Rng As Range, Cell As Range
Dim shp As Shape
Dim VarNo As Long, i As Long, j As Long, Txt As String, FntInfo As String
Set Rng = Range("C3:C7") 'Range used for collecting input data and font information for the variable
VarNo = 0
'loop used for Trial may be directly assigned to CellStr by increasing Varno by one for each cell
For Each Cell In Rng.Cells
VarNo = VarNo + 1
ReDim Preserve CellStr(1 To 2, 1 To VarNo)
Txt = Cell.Value
CellStr(1, VarNo) = Txt
FntInfo = ""
For i = 1 To Len(Txt)
If Cell.Characters(i, 1).Font.Subscript = True Then
FntInfo = FntInfo & "A"
ElseIf Cell.Characters(i, 1).Font.Superscript = True Then
FntInfo = FntInfo & "B"
Else
FntInfo = FntInfo & "C"
End If
Next i
CellStr(2, VarNo) = FntInfo
Next Cell
'again loop used for Trial may be directly assigned to CellStr from Textboxes in the sheet
For Each shp In ActiveSheet.Shapes
If shp.Type = msoTextBox Then
VarNo = VarNo + 1
ReDim Preserve CellStr(1 To 2, 1 To VarNo)
Txt = shp.TextFrame2.TextRange.Text
CellStr(1, VarNo) = Txt
FntInfo = ""
For i = 1 To Len(Txt)
If shp.TextFrame2.TextRange.Characters(i, 1).Font.Subscript = msoTrue Then
FntInfo = FntInfo & "A"
ElseIf shp.TextFrame2.TextRange.Characters(i, 1).Font.Superscript = msoTrue Then
FntInfo = FntInfo & "B"
Else
FntInfo = FntInfo & "C"
End If
Next i
CellStr(2, VarNo) = FntInfo
End If
Next
'Start of Trial code in excel to be deleted
For i = 1 To UBound(CellStr, 2)
ActiveSheet.Cells(i, 10).Value = CellStr(1, i)
ActiveSheet.Cells(i, 11).Value = CellStr(2, i)
FntInfo = CellStr(2, i)
For j = 1 To Len(FntInfo)
ActiveSheet.Cells(i, 10).Characters(j, 1).Font.Subscript = False
ActiveSheet.Cells(i, 10).Characters(j, 1).Font.Superscript = False
If Mid(FntInfo, j, 1) = "A" Then ActiveSheet.Cells(i, 10).Characters(j, 1).Font.Subscript = True
If Mid(FntInfo, j, 1) = "B" Then ActiveSheet.Cells(i, 10).Characters(j, 1).Font.Superscript = True
Next j
Next
'End of Trial code in excel to be deleted
'Powerpoint placement of data in powerpoint
Dim Pp As PowerPoint.Application
Dim Prs As Presentation
Dim Sld As Slide
Dim Pshp As Shape
Set Pp = CreateObject("Powerpoint.application")
Pp.Visible = True
Set Prs = Pp.Presentations.Open("C:\users\user\desktop\test.pptx")
Set Sld = Prs.Slides(1)
For i = 1 To UBound(CellStr, 2)
Set Pshp = Sld.Shapes(i)
Pshp.TextFrame.TextRange.Text = CellStr(1, i)
FntInfo = CellStr(2, i)
For j = 1 To Len(FntInfo)
Pshp.TextFrame.TextRange.Characters(j, 1).Font.Subscript = False
Pshp.TextFrame.TextRange.Characters(j, 1).Font.Superscript = False
If Mid(FntInfo, j, 1) = "A" Then Pshp.TextFrame.TextRange.Characters(j, 1).Font.Subscript = True
If Mid(FntInfo, j, 1) = "B" Then Pshp.TextFrame.TextRange.Characters(j, 1).Font.Superscript = True
Next j
Next
End Sub
It is suggested to Add reference of Microsoft PowerPoint Object Library and thanks for asking a good question/challenge to achieve something seemingly not possible but logically possible.
Edit: another more simplistic approach (the 1st half of the String variable contains actual string and 2nd half of the variable contains Font Info) with generalized functions is also added below
Sub Sscript2()
Dim Txt As String, Var1 As String, Var2 As String
Dim Addr As String
Var1 = GetVarFont("C6") ' 1st half of the var contains actual string and 2nd half contain font Info
Var2 = GetVarFont("C7") ' 1st half of the var contains actual string and 2nd half contain font Info
'Powerpoint placement of data in powerpoint
Dim Pp As PowerPoint.Application
Dim Prs As Presentation
Dim Sld As Slide
Dim Pshp As Object
Set Pp = CreateObject("Powerpoint.application")
Pp.Visible = True
Set Prs = Pp.Presentations.Open("C:\users\user\desktop\test.pptx")
Set Sld = Prs.Slides(1)
WriteShp Sld.Shapes(8).TextFrame.TextRange, Var1
WriteShp Sld.Shapes(9).TextFrame.TextRange, Var2
End Sub
Sub WriteShp(Ptxt As TextRange, VarX As String)
Dim i As Long
Ptxt.Text = Left(VarX, Len(VarX) / 2)
For i = 1 To Len(VarX) / 2
Ptxt.Characters(i, 1).Font.Subscript = False
Ptxt.Characters(i, 1).Font.Superscript = False
If Mid(VarX, Len(VarX) / 2 + i, 1) = "A" Then Ptxt.Characters(i, 1).Font.Subscript = True
If Mid(VarX, Len(VarX) / 2 + i, 1) = "B" Then Ptxt.Characters(i, 1).Font.Superscript = True
Next
End Sub
Function GetVarFont(Addr As String) As String
Dim Txt As String, i As Long
Txt = Range(Addr).Value
GetVarFont = Txt
For i = 1 To Len(Txt)
If Range(Addr).Characters(i, 1).Font.Subscript = True Then
GetVarFont = GetVarFont & "A"
ElseIf Range(Addr).Characters(i, 1).Font.Superscript = True Then
GetVarFont = GetVarFont & "B"
Else
GetVarFont = GetVarFont & "C"
End If
Next i
End Function

How to create a macro which will copy data from row to column, using conditions?

I am using currently v lookup to find and place values against the specific item. however, I am looking for help for a VB macro which will out the data in defined outcome.
please see 1st screen shot of raw data
second screen shot, should be the outcome.
Please note the "site" is not constant it can be any value, so I have put all site in column A .
currently V look is doing the job well. but makes the file crash sometime.
You can solve this with a Pivot Table using your original data source with NO changes in the table layout.
Drag the columns as shown below (you'll want to rename them from the default names): For Columns, drag the Date field there first. The Σ Values field will appear after you've dragged two Fields to the Values area, and should be below Date.
And with some formatting changes from the default, the result can look like:
Can you change your source data?
If you change your data to look like the table "Changed Source Data" below you can solve your issue with a pivot table.
Solution with a Pivot Table
Changed Source Data
There question can easily solved with pivot table. For practice i have create the below.
Let us assume that:
Data appears in Sheet "Data"
Results will be populated in sheet "Results"
Option Explicit
Sub Allocation()
Dim LastRow As Long, Row As Long, Column As Long, Invetory As Long, Sold As Long, Remaining As Long, LastRowRes As Long, LastColRes As Long, CurrentCol As Long, CurrentRow As Long, i As Long, y As Long
Dim iDate As Date
Dim Site As String
Dim wsData As Worksheet, wsResults As Worksheet
Dim ExcistSite As Boolean, ExcistDate As Boolean
Set wsData = ThisWorkbook.Worksheets("Data")
Set wsResults = ThisWorkbook.Worksheets("Results")
LastRow = wsData.Cells(wsData.Rows.Count, "A").End(xlUp).Row
wsResults.UsedRange.Clear
For Row = 2 To LastRow
iDate = wsData.Cells(Row, 1).Value
Site = wsData.Cells(Row, 2).Value
Invetory = wsData.Cells(Row, 3).Value
Sold = wsData.Cells(Row, 4).Value
Remaining = wsData.Cells(Row, 5).Value
If Row = 2 Then
With wsResults.Range("B1:D1")
.Merge
.Value = iDate
End With
wsResults.Range("A2").Value = "Site"
wsResults.Range("A2").Offset(1, 0).Value = Site
wsResults.Range("B2").Value = "Invetory"
wsResults.Range("B2").Offset(1, 0).Value = Invetory
wsResults.Range("C2").Value = "Sold"
wsResults.Range("C2").Offset(1, 0).Value = Sold
wsResults.Range("D2").Value = "Remaining"
wsResults.Range("D2").Offset(1, 0).Value = Remaining
Else
'Check if Site appears
LastRowRes = wsResults.Cells(wsResults.Rows.Count, "A").End(xlUp).Row
For i = 3 To LastRowRes
ExcistSite = False
If wsResults.Cells(i, 1).Value = Site Then
CurrentRow = i
ExcistSite = True
Exit For
Else
CurrentRow = i + 1
End If
Next i
If ExcistSite = False Then
wsResults.Cells(CurrentRow, 1).Value = Site
End If
'Check if date appears
LastColRes = wsResults.Cells(1, wsResults.Columns.Count).End(xlToLeft).Column
For y = 2 To LastColRes
ExcistDate = False
If wsResults.Cells(1, y).Value = iDate Then
CurrentCol = y
ExcistDate = True
Exit For
Else
CurrentCol = y + 1
End If
Next y
If ExcistDate = False Then
wsResults.Cells(2, CurrentCol + 2).Value = "Invetory"
wsResults.Cells(i, CurrentCol + 2).Value = Invetory
wsResults.Cells(2, CurrentCol + 3).Value = "Sold"
wsResults.Cells(i, CurrentCol + 3).Value = Sold
wsResults.Cells(2, CurrentCol + 4).Value = "Remaining"
wsResults.Cells(i, CurrentCol + 4).Value = Remaining
With wsResults.Range(Cells(1, LastColRes + 3), Cells(1, LastColRes + 5))
.Merge
.Value = iDate
End With
Else
wsResults.Cells(CurrentRow, CurrentCol).Value = Invetory
wsResults.Cells(CurrentRow, CurrentCol + 1).Value = Sold
wsResults.Cells(CurrentRow, CurrentCol + 2).Value = Remaining
End If
End If
Next Row
LastColRes = wsResults.Cells(1, wsResults.Columns.Count).End(xlToLeft).Column
LastRowRes = wsResults.Cells(wsResults.Rows.Count, "A").End(xlUp).Row
With wsResults.Range(Cells(1, 2), Cells(1, LastColRes))
With .Font
.Bold = True
.ThemeColor = xlThemeColorDark1
End With
With .Interior
.ThemeColor = xlThemeColorAccent1
End With
End With
With wsResults.Cells(2, 1)
With .Font
.Bold = True
.ThemeColor = xlThemeColorDark1
End With
With .Interior
.ThemeColor = xlThemeColorLight1
End With
End With
For i = 2 To LastColRes Step 3
With wsResults.Range(Cells(2, i), Cells(LastRowRes, i))
With .Interior
.ThemeColor = xlThemeColorAccent1
.TintAndShade = 0.399975585192419
End With
End With
Next i
For i = 3 To LastColRes + 3 Step 3
With wsResults.Range(Cells(2, i), Cells(LastRowRes, i + 1))
With .Font
.ThemeColor = xlThemeColorDark2
.TintAndShade = -0.249977111117893
End With
End With
Next i
With wsResults.UsedRange
.Borders.LineStyle = xlContinuous
.HorizontalAlignment = xlCenter
.VerticalAlignment = xlCenter
.EntireColumn.AutoFit
End With
End Sub

Extracting Text from a cell

I have a search function which works perfectly for searching for Exact Numerical values, However I need to adapt it so it searches for text within a cell and only extracts that text. For example it searches column 7. In column 7 there may be a cell containing the words Interface - HPT, SAS, LPT Ideally I would like to search for the word Interface - HPT then extract Only this text from the cell. I also need the search function to be able to do this for multiple different values. So for example run a search for Interface - HPT
Interface - SAS and Interface LPT separate from each other. Is this Possible ?
Here is the code I have at the moment:
Sub InterfaceMacro()
Dim Headers() As String: Headers = _
Split("Target FMECA,Part I.D,Line I.D,Part No.,Part Name,Failure Mode,Assumed System Effect,Assumed Engine Effect", ",")
Worksheets.Add().Name = "Interface"
Dim wsInt As Worksheet: Set wsInt = Sheets("Interface")
wsInt.Move after:=Worksheets(Worksheets.Count)
wsInt.Cells.Clear
Application.ScreenUpdating = False
With wsFHA
For i = 0 To UBound(Headers)
.Cells(2, i + 2) = Headers(i)
.Columns(i + 2).EntireColumn.AutoFit
Next i
.Cells(1, 2) = "Interface TABLE"
.Range(.Cells(1, 2), .Cells(1, UBound(Headers) + 2)).MergeCells = True
.Range(.Cells(1, 2), .Cells(1, UBound(Headers) + 2)).HorizontalAlignment = xlCenter
.Range(.Cells(1, 2), .Cells(2, UBound(Headers) + 2)).Font.Bold = True
End With
Dim SourceCell As Range, FirstAdr As String
Dim RowCounter As Long: RowCounter = 3
Dim SearchTarget() As String
SearchTarget = Split("9.1,18.0", ",")
For i = 0 To UBound(SearchTarget)
If Worksheets.Count > 1 Then
For j = 1 To Worksheets.Count - 1
With Sheets(j)
Set SourceCell = .Columns(7).Find(SearchTarget(i), LookAt:=xlWhole)
If Not SourceCell Is Nothing Then
FirstAdr = SourceCell.Address
Do
wsInt.Cells(RowCounter, 2).Value = SearchTarget(i)
wsInt.Cells(RowCounter, 3).Value = .Cells(SourceCell.Row, 6).Value
wsInt.Cells(RowCounter, 4).Value = .Cells(3, 10).Value
wsInt.Cells(RowCounter, 5).Value = .Cells(2, 10).Value
wsInt.Cells(RowCounter, 6).Value = .Cells(SourceCell.Row, 2).Value
For k = 0 To SourceCell.Row - 1
If .Cells(SourceCell.Row - k, 3).Value <> "continued." Then
wsFHA.Cells(RowCounter, 7).Value = .Cells(SourceCell.Row - k, 3).Value
Exit For
End If
Next k
wsInt.Cells(RowCounter, 8).Value = .Cells(SourceCell.Row, 14).Value
Set SourceCell = .Columns(7).FindNext(SourceCell)
RowCounter = RowCounter + 1
Loop While Not SourceCell Is Nothing And SourceCell.Address <> FirstAdr
End If
End With
Next j
End If
Next i
End Sub
The part I believe needs editing is this section
Dim SourceCell As Range, FirstAdr As String
Dim RowCounter As Long: RowCounter = 3
Dim SearchTarget() As String
SearchTarget = Split("9.1,18.0", ",")
For i = 0 To UBound(SearchTarget)
If Worksheets.Count > 1 Then
For j = 1 To Worksheets.Count - 1
With Sheets(j)
Set SourceCell = .Columns(7).Find(SearchTarget(i), LookAt:=xlWhole)
If Not SourceCell Is Nothing Then
FirstAdr = SourceCell.Address
You can define the array to search the same way as you define it for numbers.
To search also part of the cell content you need to change .Find(SearchTarget(i), LookAt:=xlWhole) to .Find(SearchTarget(i), LookAt:=xlPart).
VBA looks in formulas / results the same way as it works in Find / Replace dialog. (set .LookIn to either xlValues or xlFormulas)

Resources