How to find the first incident of any signature in a list/array within an email? - vba

I want to give credit to an agent, if they're the one that sent the message, but only if their signature is at the top of the email.
Here is what I have. The search order is off. The code searches for one name at a time, and clear through the document. I need it to search for All names, the first one that hits in the body of the email.
Sub CountOccurences_SpecificText_In_Folder()
Dim MailItem As Outlook.MailItem
Dim strSpecificText As String
Dim tmpStr As String
Dim x As Integer
Dim Count As Integer
Dim HunterCnt As Integer
Dim SunmolaCnt As Integer
Dim RodriguezCnt As Integer
Dim MammedatyCnt As Integer
Dim MitchellCnt As Integer
Dim TannerCnt As Integer
Dim TAYLORCnt As Integer
Dim WilsonCnt As Integer
Dim WilliamsCnt As Integer
Dim GrooverCnt As Integer
Dim TyreeCnt As Integer
Dim ChapmanCnt As Integer
Dim LukerCnt As Integer
Dim KlinedinstCnt As Integer
Dim HicksCnt As Integer
Dim NATHANIALCnt As Integer
Dim SkinnerCnt As Integer
Dim SimonsCnt As Integer
Dim AgentNames(14) As Variant
AgentNames(0) = "Simons"
AgentNames(1) = "Skinner"
AgentNames(2) = "Mammedaty"
AgentNames(3) = "Hunter"
AgentNames(4) = "Sunmola"
AgentNames(5) = "Rodriguez"
AgentNames(6) = "Mitchell"
AgentNames(7) = "Tanner"
AgentNames(8) = "Taylor"
AgentNames(9) = "Wilson"
AgentNames(10) = "Williams"
AgentNames(11) = "Groover"
AgentNames(12) = "Tyree"
AgentNames(13) = "Chapman"
AgentNames(14) = "Luker"
x = 0
While x < ActiveExplorer.Selection.Count
x = x + 1
Set MailItem = ActiveExplorer.Selection.item(x)
tmpStr = MailItem.Body
For Each Agent In AgentNames
If InStr(tmpStr, Agent) <> 0 Then
If Agent = "Assunta" Then
HunterCnt = HunterCnt + 1
GoTo skip
End If
If Agent = "Sunmola" Then
SunmolaCnt = SunmolaCnt + 1
GoTo skip
End If
If Agent = "Rodriguez" Then
RodriguezCnt = RodriguezCnt + 1
GoTo skip
End If
If Agent = "Mammedaty" Then
MammedatyCnt = MammedatyCnt + 1
GoTo skip
End If
If Agent = "Mitchell" Then
MitchellCnt = MitchellCnt + 1
GoTo skip
End If
If Agent = "Tanner" Then
TannerCnt = TannerCnt + 1
GoTo skip
End If
If Agent = "Taylor" Then
TAYLORCnt = TAYLORCnt + 1
GoTo skip
End If
If Agent = "Wilson" Then
WilsonCnt = WilsonCnt + 1
GoTo skip
End If
If Agent = "Williams" Then
WilliamsCnt = WilliamsCnt + 1
GoTo skip
End If
If Agent = "Groover" Then
GrooverCnt = GrooverCnt + 1
GoTo skip
End If
If Agent = "Tyree" Then
TyreeCnt = TyreeCnt + 1
GoTo skip
End If
If Agent = "Chapman" Then
ChapmanCnt = ChapmanCnt + 1
GoTo skip
End If
If Agent = "Luker" Then
LukerCnt = LukerCnt + 1
GoTo skip
End If
If Agent = "Hicks" Then
HicksCnt = HicksCnt + 1
GoTo skip
End If
End If
Next
skip:
Count = Count + 1
Wend
MsgBox "Found " & vbCrLf & "Hunter Count: " & HunterCnt & vbCrLf & "Sunmola Count: " & SunmolaCnt & vbCrLf & "Rodriguez Count: " & RodriguezCnt & vbCrLf & "Mammedaty Count: " & MammedatyCnt & vbCrLf & "Mitchell Count: " & MitchellCnt & vbCrLf & "Tanner Count: " & TannerCnt & vbCrLf & "Taylor Count: " & TAYLORCnt & vbCrLf & "Wilson Count: " & WilsonCnt & vbCrLf & "Williams Count: " & WilliamsCnt & vbCrLf & "Groover Count: " & GrooverCnt & vbCrLf & "Tyree Count: " & TyreeCnt & vbCrLf & "Chapman Count: " & ChapmanCnt & vbCrLf & "Luker Count: " & LukerCnt & vbCrLf & " in: " & Count & " emails"
End Sub

InStr returns positional information. While it is difficult to find the first occurrence of an array member within the text (you would need to build and compare matches), you can find the first position of each name then find which came first.
For example (untested)
Sub CountOccurences_SpecificText_In_Folder()
Dim MailItem As Outlook.MailItem
Dim i As Long, x As Long, position As Long, First As Long
Dim AgentNames() As String
AgentNames = Split("Simons,Skinner,Mammedaty,Hunter,Sunmola,Rodriguez,Mitchell,Tanner,Taylor,Wilson,Williams,Groover,Tyree,Chapman,Luker", ",")
Dim AgentCount(LBound(AgentNames) To UBound(AgentNames)) As Long
For i = LBound(AgentCount) To UBound(AgentCount)
AgentCount(i) = 0
Next i
For Each MailItem In ActiveExplorer.Selection
x = 0
For i = LBound(AgentNames) To UBound(AgentNames)
position = InStr(MailItem.Body, AgentNames(i))
If x > 0 Then
If position < x Then
x = position
First = i
End If
Else
If position > 0 Then
x = position
First = i
End If
End If
Next i
AgentCount(First) = AgentCount(First) + 1
Next MailItem
For i = LBound(AgentNames) To UBound(AgentNames)
Debug.Print AgentNames(i) & " Count: " & AgentCount(i)
Next i
End Sub

The idea in the previous answer may be better implemented like this:
Option Explicit
Sub CountOccurences_SpecificText_SelectedItems()
Dim objItem As Object
Dim objMail As MailItem
Dim i As Long
Dim j As Long
Dim x As Long
Dim position As Long
Dim First As Long
Dim AgentNames() As String
AgentNames = Split("Simons,Skinner,Mammedaty,Hunter,Sunmola,Rodriguez,Mitchell,Tanner,Taylor,Wilson,Williams,Groover,Tyree,Chapman,Luker", ",")
ReDim AgentCount(LBound(AgentNames) To UBound(AgentNames)) As Long
For j = 1 To ActiveExplorer.Selection.Count
Set objItem = ActiveExplorer.Selection(j)
' Verify before attempting to return mailitem poroperties
If TypeOf objItem Is MailItem Then
Set objMail = objItem
Debug.Print
Debug.Print "objMail.Subject: " & objMail.Subject
x = Len(objMail.Body)
For i = LBound(AgentNames) To UBound(AgentNames)
Debug.Print
Debug.Print "AgentNames(i): " & AgentNames(i)
position = InStr(objMail.Body, AgentNames(i))
Debug.Print " position: " & position
If position > 0 Then
If position < x Then
x = position
First = i
End If
End If
Debug.Print "Lowest position: " & x
Debug.Print " Current first: " & AgentNames(First)
Next i
If x < Len(objMail.Body) Then
AgentCount(First) = AgentCount(First) + 1
Debug.Print
Debug.Print AgentNames(First) & " was found first"
Else
Debug.Print "No agent found."
End If
End If
Next
For i = LBound(AgentNames) To UBound(AgentNames)
Debug.Print AgentNames(i) & " Count: " & AgentCount(i)
Next i
End Sub

Related

How can I prevent VBA code, used to draw up a list of unique words from a word document, from slowing down as the document get's longer

I have used some code from the internet, modified slightly for my specific use case, to draw up a list of unique words from a word document, the code works without a problem, but the time to execute the code seems to grow exponentially as the document length increases. Can anyone give me any suggestions to speed up the code when working with very long documents?
Sub UniqueWordList()
Dim wList As New Collection
Dim wrd
Dim chkwrd
Dim sTemp As String
Dim k As Long
Dim cWrd As Long
Dim tWrd As Long
Dim nWrd As String
Dim Flag As Boolean
Flag = False
tWrd = ActiveDocument.Range.Words.Count
cWrd = 0
For Each wrd In ActiveDocument.Range.Words
cWrd = cWrd + 1
If cWrd Mod 100 = 0 Then
Application.StatusBar = "Updating: " & (cWrd)
End If
If Flag Then
Flag = False
GoTo nw
End If
If cWrd < tWrd Then
nWrd = ActiveDocument.Words(cWrd + 1)
nWrd = Trim(LCase(nWrd))
End If
sTemp = Trim(LCase(wrd))
If sTemp = "‘" Then
sTemp = sTemp & nWrd
Flag = True
End If
If sTemp Like "*[a-zA-Z]*" Then
k = 0
For Each chkwrd In wList
k = k + 1
If chkwrd = sTemp Then GoTo nw
If chkwrd > sTemp Then
wList.Add Item:=sTemp, Before:=k
GoTo nw
End If
Next chkwrd
wList.Add Item:=sTemp
End If
nw:
Next wrd
sTemp = "There are " & ActiveDocument.Range.Words.Count & " words "
sTemp = sTemp & "in the document, before this summary, but there "
sTemp = sTemp & "are only " & wList.Count & " unique words."
ActiveDocument.Range.Select
Selection.Collapse Direction:=wdCollapseEnd
Selection.TypeText vbCrLf & sTemp & vbCrLf
For Each chkwrd In wList
Selection.TypeText chkwrd & vbCrLf
Next chkwrd
End Sub
After some suggestions I modified my code to use a scripting dictionary, this however does not seem to have solved the problem. Also to answer the concern regarding my message at the end, I understand that the wording is off, what I want is a list of words from the document but each word only once.
Sub UniqueWordListMi()
Dim wList() As String
Dim sTemp As String
Dim cWrd As Long
Dim tWrd As Long
Dim nWrd As String
Dim Flag As Boolean
Dim IsInArray As Boolean
Dim arrsize As Long
Dim rra2 As Variant
arrsize = 0
Flag = False
tWrd = ActiveDocument.Range.Words.Count
cWrd = 1
ReDim Preserve wList(0 To arrsize)
wList(arrsize) = "UNQ"
For Each wrd In ActiveDocument.Range.Words
If cWrd Mod 100 = 0 Then
Application.StatusBar = "Updating" & (cWrd)
End If
If Flag Then
Flag = False
GoTo nw
End If
If cWrd < tWrd Then
nWrd = ActiveDocument.Words(cWrd + 1)
nWrd = Trim(LCase(nWrd))
End If
sTemp = Trim(LCase(wrd))
If sTemp = "‘" Then
sTemp = sTemp & nWrd
Flag = True
End If
If sTemp Like "*[a-zA-Z]*" Then
ReDim Preserve wList(0 To arrsize)
wList(arrsize) = sTemp
arrsize = arrsize + 1
End If
nw:
cWrd = cWrd + 1
Next wrd
Set Dict = CreateObject("scripting.dictionary")
For i = 0 To UBound(wList)
If (Not Dict.Exists(CStr(wList(i)))) Then Dict.Add CStr(wList(i)), wList(i) 'Next i
Next i
rra2 = Dict.Items
sTemp = "There are " & ActiveDocument.Range.Words.Count & " words "
sTemp = sTemp & "in the document, before this summary, but there "
sTemp = sTemp & "are only " & UBound(wList) & " unique words."
ActiveDocument.Range.Select
Selection.Collapse Direction:=wdCollapseEnd
Selection.TypeText vbCrLf & sTemp & vbCrLf
For u = 0 To UBound(rra2)
Selection.TypeText vbCrLf & rra2(u) & vbCrLf
Next u
End Sub
#AlexK beat me to it with a comment on using a Scripting.Dictionary.
Something like this might help
Option Explicit
Public Function CountUniqueWords(ByRef ipRange As Word.Range) As Scripting.Dictionary
Dim myUniqueWords As Scripting.Dictionary
Set myUniqueWords = New Scripting.Dictionary
Dim myPara As Variant
For Each myPara In ipRange.Paragraphs
Dim myWord As Variant
For Each myWord In Split(myPara.Range.Text)
If myUniqueWords.Exists(myWord) Then
myUniqueWords.Item(myWord) = myUniqueWords.Item(myWord) + 1
Else
myUniqueWords.Add myWord, 1
End If
Next
Next
Set CountUniqueWords = myUniqueWords
End Function
Some polishing might be required to meet your specific requirements.
You can't help some increase in processing time as the document gets longer but as the access to the document is limited to paragraphs rather than words is should proceed somewhat faster.
Try the following code. It uses the dictionary directly with the rules of your code.
Note that this will only improve your code. But still, the longer the document will get, the more words need to be checked and the more time it will need. That fact will not change, you can just optimize it by using the dictionary directly but more words need more time to check.
Option Explicit
Sub UniqueWordListMi()
Dim wList As Object
Set wList = CreateObject("scripting.dictionary")
Dim sTemp As String
Dim cWrd As Long
Dim tWrd As Long
Dim nWrd As String
Dim Flag As Boolean
Dim IsInArray As Boolean
Dim arrsize As Long
Dim rra2 As Variant
arrsize = 0
Flag = False
tWrd = ActiveDocument.Range.Words.Count
cWrd = 1
Dim wrd As Variant
For Each wrd In ActiveDocument.Range.Words
If cWrd Mod 100 = 0 Then
Application.StatusBar = "Updating" & (cWrd)
End If
If Flag Then
Flag = False
GoTo nw
End If
If cWrd < tWrd Then
nWrd = ActiveDocument.Words(cWrd + 1)
nWrd = Trim(LCase(nWrd))
End If
sTemp = Trim(LCase(wrd))
If sTemp = "‘" Then
sTemp = sTemp & nWrd
Flag = True
End If
If sTemp Like "*[a-zA-Z]*" Then
If Not wList.Exists(sTemp) Then
wList.Add sTemp, 1
Else
wList.Item(sTemp) = wList.Item(sTemp) + 1
End If
cWrd = cWrd + 1
End If
nw:
Next wrd
sTemp = "There are " & (cWrd - 1) & " words "
sTemp = sTemp & "in the document, before this summary, but there "
sTemp = sTemp & "are only " & wList.Count & " distinct words."
ActiveDocument.Range.Select
Selection.Collapse Direction:=wdCollapseEnd
Selection.TypeText vbCrLf & sTemp & vbCrLf
Dim chkwrd As Variant
For Each chkwrd In wList
Selection.TypeText chkwrd & vbTab & wList.Item(chkwrd) & " times" & vbCrLf
Next chkwrd
End Sub
The following example:
This is an example test where every word is unique except one.
There are 12 words in the document, before this summary, but there are only 11 distinct words.
this 1 times
is 2 times
an 1 times
example 1 times
test 1 times
where 1 times
every 1 times
word 1 times
unique 1 times
except 1 times
one 1 times
With everyone's help and some additional reading, as well as some help from a reddit user this code work's perfectly:
Sub UniqueWordListFast()
Dim WordDictionary As Object
Dim SourceText As Document
Dim objWord As Object
Dim sTemp As String, strWord As String, nxtWord As String
Dim count As Long
count = 0
Set WordDictionary = CreateObject("Scripting.Dictionary")
Set SourceText = Application.ActiveDocument
For Each objWord In SourceText.Range.Words
count = count + 1
strWord = Trim(objWord.Text)
If strWord = nxtWord Then GoTo nw
If strWord Like "*[a-z]*" Then WordDictionary(strWord) = strWord
If strWord Like "‘" Then
nxtWord = Trim(SourceText.Words(count + 1))
strWord = strWord & nxtWord
WordDictionary(strWord) = strWord
End If
nw:
Next
sTemp = "[DOCUMENT] " & vbTab & SourceText.Name & vbCrLf & vbCrLf & _
"There are " & SourceText.Range.Words.count & " words in the document, " & _
"before this summary, but there are only " & WordDictionary.count & " unique words."
Dim NewDocument As Document
Set NewDocument = Documents.Add
NewDocument.Range.Text = sTemp & vbCrLf & Join(WordDictionary.Keys, vbCrLf)
End Sub
Extremely fast and efficient. Thank you everyone!

Search FlagRequest for single or multiple text combinations

In my inbox there are emails where the sender communicates either single or multiple seminars or event codes.
For example, AI-G167 and/or HR-T245. I flag those emails with category and flag request and this helps me add functionality in my code.
My filter only works when FlagRequest has a single event code and fails when I mark FlagRequest with a delimited value, e.g "AI-G167, HR-T245".
Category_Filter = "[Categories] = 'Seminars' And [FlagRequest] = " & EventCode
Is there any way, my filter could work in this scenario? It means that email would serve my purpose even if there are two different events to be held on a single day at different times.
If Restrict does not support like for .FlagRequest there is InStr.
Option Explicit ' Consider this mandatory
' Tools | Options | Editor tab
' Require Variable Declaration
' If desperate declare as Variant
Sub FlagRequest_multiple_values()
Dim oItems As Items
Dim oItemsRes As Items
Dim Category_Filter As String
Dim Category_Flag_Filter As String
Dim EventCode As String
Dim i As Long
Dim resItemsCount As Long
Dim matchCount As Long
Set oItems = Session.GetDefaultFolder(olFolderInbox).Folders("FlagRequestTest").Items
EventCode = "AI-G167"
'EventCode = "HR-T245"
Debug.Print
Debug.Print "EventCode......: " & EventCode
' with single quotes added to variable
Category_Flag_Filter = _
"[Categories] = 'Seminars' And [FlagRequest] = " & "'" & EventCode & "'"
Debug.Print
Debug.Print "Category_Flag_Filter......: " & Category_Flag_Filter
Set oItemsRes = oItems.Restrict(Category_Flag_Filter)
Debug.Print "Category_Flag_Filter count: " & oItemsRes.Count
Category_Filter = "[Categories] = 'Seminars'"
Debug.Print
Debug.Print "Category_Filter......: " & Category_Filter
Set oItemsRes = oItems.Restrict(Category_Filter)
Debug.Print "Category_Filter count: " & oItemsRes.Count
If oItemsRes.Count > 0 Then
resItemsCount = oItemsRes.Count
For i = 1 To resItemsCount
With oItemsRes(i)
Debug.Print i & " Subject......: " & .Subject
Debug.Print " FlagRequest: " & .FlagRequest
If InStr(.FlagRequest, EventCode) > 0 Then
matchCount = matchCount + 1
Else
Debug.Print " *** No match ***"
End If
End With
Next
End If
Debug.Print matchCount & " matches of " & resItemsCount
End Sub

Remove floor shadows in solid works render by macro

I'm trying develop a macro that runs renders and saves them automatically. The files (with path) are listed, and extracted from an Excel file, then opened and rendered.
This part works fine, but now I would like to remove the floor shades (and floor reflections) within the VBA code. I tried to record a macro while turning off the floor shades in a random SolidWorks file, but SolidWorks unfortunately doesn't record this part.
Does any one have a solution for this?
Thanks in advance
'
******************************************************************************
' C:\Users\Omar\AppData\Local\Temp\swx11684\Macro1.swb - macro recorded on 11/25/16 by Omar
' ******************************************************************************
Sub main()
Dim swApp As Object
Dim Part As Object
Dim boolstatus As Boolean
Dim longstatus As Long, longwarnings As Long
Dim status As Boolean
Set swApp = Application.SldWorks
Dim i As String
Dim j As String
Dim y As Integer
Dim z As String
Dim n As Integer
Dim m As Integer
Dim swModel As SldWorks.ModelDoc2
Dim swRayTraceRenderer As SldWorks.RayTraceRenderer
Dim swRayTraceRenderOptions As SldWorks.RayTraceRendererOptions
Dim errors As Long
Dim warnings As Long
Dim filePath As String
Dim Scene As SldWorks.SWScene
Dim swConfig As SldWorks.Configuration
Dim swPoint As SldWorks.MathPoint
Dim point As Variant
Dim swVector As SldWorks.MathVector
Dim vect As Variant
'Dim xlApp As Object, xlWB As Object
'Set xlApp = CreateObject("Excel.Application")
'i = file name
'j = file extention
'i = "bp01p0006" example
'j = "simbeton - Solidworks\bp - betonplaten\bp01 - simvlak\" example
'Set xlWB = xlApp.Workbooks.Open(“C:\Users\Omar\Desktop\Renders Rob\Lijst.xlsx”)
y = 0
n = 0
Do While n < 5
Dim xlApp As Excel.Application
Dim xlWB As Excel.Workbook
Set xlApp = New Excel.Application
Set xlWB = xlApp.Workbooks.Open("C:\Users\Omar\Desktop\Renders Rob\Lijst.xlsx")
If xlWB.Worksheets(1).Range("A1").offset(y, 0) = "" Then
y = y + 1
n = n + 1
Else
j = xlWB.Worksheets(1).Range("A1").offset(y, 0).value
i = xlWB.Worksheets(1).Range("A1").offset(y, 1).value
z = xlWB.Worksheets(1).Range("A1").offset(y, 2).value
xlWB.Worksheets(1).Range("A1").offset(y, 0) = ""
y = y + 1
End If
Set xlWB = Nothing
Set xlApp = Nothing
filePath = "" & j & "\" & i & ".SLDPRT"
Set swModel = swApp.OpenDoc6(filePath, swDocPART, swOpenDocOptions_Silent, "", errors, warnings)
Set Part = swApp.ActiveDoc
Set swApp = _
Application.SldWorks
Dim myModelView As Object
Set myModelView = Part.ActiveView
myModelView.AddPerspective
Part.ViewZoomtofit2
Part.ViewZoomtofit2
Part.ViewZoomtofit2
Part.ViewZoomtofit2
Part.ViewZoomtofit2
Part.ShowNamedView2 "*Isometric", 7
Part.ViewZoomtofit2
Part.ViewDisplayShaded
Dim activeModelView As Object
Set activeModelView = Part.ActiveView
activeModelView.DisplayMode = swViewDisplayMode_e.swViewDisplayMode_ShadedWithEdges
Part.ClearSelection2 True
boolstatus = Part.Extension.SketchBoxSelect("0.000000", "0.000000", "0.000000", "0.000000", "0.000000", "0.000000")
Part.ViewDisplayShaded
' Access PhotoView 360
Set swRayTraceRenderer = swApp.GetRayTraceRenderer(swPhotoView)
' Get and set rendering options
Set swRayTraceRenderOptions = swRayTraceRenderer.RayTraceRendererOptions
'Get current rendering values
Debug.Print "Current rendering values"
Debug.Print " ImageHeight = " & swRayTraceRenderOptions.ImageHeight
Debug.Print " ImageWidth = " & swRayTraceRenderOptions.ImageWidth
Debug.Print " ImageFormat = " & swRayTraceRenderOptions.ImageFormat
Debug.Print " PreviewRenderQuality = " & swRayTraceRenderOptions.PreviewRenderQuality
Debug.Print " FinalRenderQuality = " & swRayTraceRenderOptions.FinalRenderQuality
Debug.Print " BloomEnabled = " & swRayTraceRenderOptions.BloomEnabled
Debug.Print " BloomThreshold = " & swRayTraceRenderOptions.BloomThreshold
Debug.Print " BloomRadius = " & swRayTraceRenderOptions.BloomRadius
Debug.Print " ContourEnabled = " & swRayTraceRenderOptions.ContourEnabled
Debug.Print " ShadedContour = " & swRayTraceRenderOptions.ShadedContour
Debug.Print " ContourLineThickness = " & swRayTraceRenderOptions.ContourLineThickness
Debug.Print " ContourLineColor = " & swRayTraceRenderOptions.ContourLineColor
Debug.Print " "
'Change rendering values
Debug.Print "New rendering values"
swRayTraceRenderOptions.ImageHeight = 405
Debug.Print " ImageHeight = " & swRayTraceRenderOptions.ImageHeight
swRayTraceRenderOptions.ImageWidth = 720
Debug.Print " ImageWidth = " & swRayTraceRenderOptions.ImageWidth
swRayTraceRenderOptions.ImageFormat = swImageFormat_PNG
Debug.Print " ImageFormat = " & swRayTraceRenderOptions.ImageFormat
swRayTraceRenderOptions.PreviewRenderQuality = swRenderQuality_Better
Debug.Print " PreviewRenderQuality = " & swRayTraceRenderOptions.PreviewRenderQuality
swRayTraceRenderOptions.FinalRenderQuality = swRenderQuality_Best
Debug.Print " FinalRenderQuality = " & swRayTraceRenderOptions.FinalRenderQuality
swRayTraceRenderOptions.BloomEnabled = False
Debug.Print " BloomEnabled = " & swRayTraceRenderOptions.BloomEnabled
swRayTraceRenderOptions.BloomThreshold = 0
Debug.Print " BloomThreshold = " & swRayTraceRenderOptions.BloomThreshold
swRayTraceRenderOptions.BloomRadius = 0
Debug.Print " BloomRadius = " & swRayTraceRenderOptions.BloomRadius
swRayTraceRenderOptions.ContourEnabled = False
Debug.Print " ContourEnabled = " & swRayTraceRenderOptions.ContourEnabled
swRayTraceRenderOptions.ShadedContour = False
Debug.Print " ShadedContour = " & swRayTraceRenderOptions.ShadedContour
swRayTraceRenderOptions.ContourLineThickness = 0
Debug.Print " ContourLineThickness = " & swRayTraceRenderOptions.ContourLineThickness
swRayTraceRenderOptions.ContourLineColor = 255
Debug.Print " ContourLineColor = " & swRayTraceRenderOptions.ContourLineColor
' Display the preview window
status = swRayTraceRenderer.DisplayPreviewWindow
' Close render
status = swRayTraceRenderer.CloseRayTraceRender
' Invoke final render window
status = swRayTraceRenderer.InvokeFinalRender
' Abort final render window
status = swRayTraceRenderer.AbortFinalRender
' Render to Windows Bitmap format
status = swRayTraceRenderer.RenderToFile("C:\Users\Omar\Desktop\Renders Rob\" & i & z & ".png", 0, 0)
swRayTraceRenderOptions.FinalRenderQuality = swRenderQuality_Good
' Render to HDR format (format extension omitted)
status = swRayTraceRenderer.RenderToFile("C:\Users\Omar\Desktop\Renders Rob\" & i & z, 0, 0)
Set swRayTraceRenderOptions = Nothing
' Close render
status = swRayTraceRenderer.CloseRayTraceRender
swApp.QuitDoc i
Loop
End Sub
With Solidworks tutorials : FloorShadows Property (ISwScene)
Option Explicit
Dim Scene As SldWorks.SWScene
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swConfig As SldWorks.Configuration
Dim swPoint As SldWorks.MathPoint
Dim swVector As SldWorks.MathVector
Dim point As Variant
Dim vect As Variant
Sub main()
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
Set swConfig = swModel.GetActiveConfiguration
Debug.Print "Configuration: " & swConfig.Name
Set Scene = swConfig.GetScene
Dim P2SFilename As String
Scene.GetP2SFileName P2SFilename
Debug.Print "Scene file: " & P2SFilename
Scene.GetFloorNormal swPoint, swVector
point = swPoint.ArrayData
Debug.Print "Scene floor normal point: " & point(0) & ", " & point(1) & ", " & point(2)
vect = swVector.ArrayData
Debug.Print "Scene floor normal vector: " & vect(0) & ", " & vect(1) & ", " & vect(2)
Dim value As Boolean
Scene.FloorShadows = False '<- Here !
value = Scene.FloorShadows 'debug
Scene.BackgroundType = swSceneBackgroundType_e.swBackgroundType_UseEnvironment
Debug.Print "Type of scene background as defined in swSceneBackgroundType_e: " & Scene.BackgroundType
Debug.Print "Scene background environment image file: " & Scene.BackgroundEnvImage
Debug.Print "Scene background image file: " & Scene.BackgroundImage
Debug.Print "Scene environment rotation: " & Scene.EnvironmentRotation
Scene.FitToSWWindow = True
Debug.Print "Stretch to fit in SOLIDWORKS window? " & Scene.FitToSWWindow
Debug.Print "Scale the scene floor uniformly? " & Scene.FixedAspectRatio
Debug.Print "Flip the scene floor direction? " & Scene.FloorDirection
Debug.Print "Automatically resize the scene floor based on the model bounding box? " & Scene.FloorAutoSize
Debug.Print "Distance between scene floor and model: " & Scene.FloorOffset
Debug.Print "Flip the scene floor offset direction? " & Scene.FloorOffsetDirection
Scene.FloorReflections = True
Debug.Print "Show model reflections on the scene floor? " & Scene.FloorReflections
Debug.Print "Scene floor rotation: " & Scene.FloorRotation
Debug.Print "Show model shadows on the scene floor? " & Scene.FloorShadows
Debug.Print "Keep the scene background when changing the scene? " & Scene.KeepBackground
Scene.FlattenFloor = True
Debug.Print "Flatten the scene floor of the spherical environment? " & Scene.FlattenFloor
Debug.Print "Horizon height: " & Scene.HorizonHeight
Debug.Print "Environment size: " & Scene.EnvironmentSize
End Sub

Count Outlook VBA attachment

Can you help me to improve the below VBA code to be able to correctly count e-mails + attachments form a selected range (outlook 2010)
Sub CountAttachmentsMulti()
Set mySelect = Outlook.ActiveExplorer.Selection
For Each Item In mySelect
j = Item.Attachments.Count + j
i = i + 1
Next Item
MsgBox "Selected " & i & " messages with " & j & " attachements"
End Sub
That is the code the problem is that counts also as attachments the picture in the signatures and give a wrong count meaning more attachments then the actually are
Can you help to amend the code to bypass from counting the images in signatures
BR
Gabi
Try this
Sub CountAttachmentsValid()
Dim olkItem As Outlook.mailitem
Dim olkAttachment As Outlook.attachment
Dim strFilename As String
Dim strExtension As String
Dim lngExtIndex As Long
Dim strBaseFilename As String
Dim cnt As Long
Dim mySelect As Selection
Dim iExt As Long
Dim validExtString As String
Dim validExtArray() As String
validExtString = ".doc .docx .xls .xlsx .msg .pdf .txt" ' <---- Update as needed
validExtArray = Split(validExtString, " ")
Set mySelect = Outlook.ActiveExplorer.Selection
For Each olkItem In mySelect
For Each olkAttachment In olkItem.Attachments
On Error GoTo cannotPerformOperation
strFilename = olkAttachment.FileName
lngExtIndex = InStrRev(strFilename, ".")
strBaseFilename = Left(strFilename, lngExtIndex - 1)
strExtension = Mid(strFilename, lngExtIndex)
For iExt = 0 To UBound(validExtArray)
If LCase(strExtension) = LCase(validExtArray(iExt)) Then
cnt = cnt + 1
Exit For
End If
Next iExt
skipped:
Next olkAttachment
Next olkItem
GoTo exiting
cannotPerformOperation:
'Debug.Print " ** " & olkAttachment.DisplayName & " not counted"
Resume skipped
exiting:
MsgBox "Selected " & mySelect.count & " messages with " & cnt & " recognized attachments"
End Sub

VBA - Loop through x items in blocks of 100 x times

I've been struggling with this for a day now.
I have a list box that is populated with x items. Could be 1 - x
I need to take all the items in the list box and format them into a string
which I submit into an oracle database. I'm using INLIST on the SQL side and because of that I can only have a maximum of 100 items in my string.
So for example if I was to have 547 items in the listbox, I would iterate through all 547 items, but at every 100 I would submit into the database, returning my result into my collection class, finishing with the last 47.
here's what i have so far. There is some attempts to solve my problem in the code so if it's confusing i'll try to explain.
Public Function SearchBMS()
On Error GoTo HandleError
Dim rst As ADODB.Recordset
Dim sESN As String
Dim i As Integer
Dim x As Integer
Dim maxrec As Integer
Dim itemcnt As Integer
Dim iBlockCount As Integer
With frmEngineCampaignSearch.lstbxESNNumbers
itemcnt = .ListCount - 2
'iBlockCount = GetBlockCount(itemcnt)
x = 0
maxrec = 100
Debug.Assert itemcnt = 200
For i = 0 To itemcnt
For x = i To maxrec
MsgBox "test", vbOKOnly
i = i + 100
Next x
If i = itemcnt Then ' if I = last item than we put the closing parenthesis on our string
sESN = sESN & "'" & .list(i) & "'"
Else
sESN = sESN & "'" & .list(i) & "' , " ' otherwise there are more items so we seperate by comma
End If
If itemcnt <= 100 Then
Set rst = Nothing
'Set rst = rstGetCustomerInfo(sESN)
'LoadRSTToCollection rst
elseif
While x = maxrec
MsgBox "submit first 100", vbOKOnly
'Set rst = Nothing
'Set rst = rstGetCustomerInfo(sESN)
'LoadRSTToCollection rst
sESN = gC_sEMPTY_STRING
maxrec = maxrec + 100
Wend
x = x + 1
Next i
End With
HandleError:
If Err.Number > 0 Then
MsgBox Err.Number & ": " & Err.Description
End If
This function is to get the number of times I would have to perform the submission but i hit a road block on how to use it within the for loop
Public Function GetBlockCount(ByRef lItemCnt As Long) As Integer
Dim x As Double
If lItemCnt <= 100 Then
GetBlockCount = 1
Exit Function
ElseIf lItemCnt > 100 Then
x = Round(lItemCnt / 100)
If lItemCnt Mod 100 > 0 Then
x = x + 1
Else
GetBlockCount = x
Exit Function
End If
End If
End Function
Any help would be much appreciated.
I think you need to clean it out and make it more readable. Then look at it and the solution will be much clearer.
Here is a simple skeleton of what it should look like:
I = 100
Txt = Get100Requests(I)
Do While Txt <> ""
'use txt
I = I + 100
Txt = Get100Requests(I)
Loop
Function Get100Requests(FromItem As Integer) As String
If FromItem => frmEngineCampaignSearch.lstbxESNNumbers.ListCount Then Exit Function
Dim I As Integer
I + FromItem
Do While I < FromItem + 99 And I < frmEngineCampaignSearch.lstbxESNNumbers.ListCount
Get100Requests = Get100Requests & "'" & frmEngineCampaignSearch.lstbxESNNumbers.list(i) & "', "
I = I + 1
Loop
Get100Requests = Left(Get100Requests, Len(Get100Requests)-2)
Exit Function