I'm preparing a quiz using on PowerPoint using the controllers of VBA scripts. My aim to set multiple questions, each has 4 choices.
I've set everything, when trying to run (starting with the method: "BeginQuiz") it's interrupted by the following error:
SlideShowWindows (unknown number) Integer out of range
My code is below:
Const NOOFQS = 4
'Used to manipulated the unicode values of bulleted lists
Const UD_CODE_1 = 111
Const UD_CODE_2 = 8226
Public QNo As Integer
Public ExitFlag As Boolean
Public Qs() As String
Public Choices() As String
Public Ans() As Integer
Public UserAns() As Integer
Sub NextSlide()
' Store the ans for later
'UserAns(QNo - 1) = 1
If QNo < NOOFQS Then
QNo = QNo + 1
SlideShowWindows(1).Presentation.Slides("QSlide").Shapes(1).TextFrame.TextRange.Text = Qs(QNo - 1)
AssignValues
Else
Call StopQuiz
End If
DoEvents
End Sub
Sub PreviousSlide()
Static X As Integer
If QNo > 1 Then
QNo = QNo - 1
AssignValues
End If
End Sub
Sub StopQuiz(Optional EndType As Boolean = False)
' EndType is used as a boolean Flag to indicate whether the user ran out of time
' or whether it was normal exit
Dim ScoreCard As Integer
Dim Ctr As Integer
ExitFlag = True
With SlideShowWindows(1)
For Ctr = 0 To NOOFQS - 1
If Ans(Ctr) = UserAns(Ctr) Then ScoreCard = ScoreCard + 1
Next Ctr
If EndType = False Then
.Presentation.Slides("EndSlide").Shapes("Closing").TextFrame.TextRange.Text = "Your score is : " & ScoreCard & " correct out of " & NOOFQS
Else
.Presentation.Slides("EndSlide").Shapes("Closing").TextFrame.TextRange.Text = "Sorry!!! Either you ran out of time or you chickened out" _
& vbCrLf & "Better luck next time." & vbCrLf _
& "Your score is: " & ScoreCard & " correct out of " & NOOFQS
End If
.View.GotoSlide (.Presentation.Slides("EndSlide").SlideIndex)
End With
End Sub
Sub StopIt()
Call StopQuiz(True)
End Sub
Sub BeginQuiz()
Dim Ctr As Integer
ReDim Qs(NOOFQS)
ReDim Ans(NOOFQS)
ReDim UserAns(NOOFQS)
ReDim Choices(NOOFQS, 4)
' All the questions
Qs(0) = "1) ãä Ãæá ãä ÝÊÍ ÇáÞÏÓ ÈÚÏ ÚãÑ¿"
Qs(1) = "2) ãä åí Ãæá ãä ÃÓáãÊ ãä ÇáäÓÇÁ¿"
Qs(2) = "3) ãÇ åí ÇáãäØÞÉ ÇáÊí ÍÑÑåÇ ãÍãÏ ÇáÝÇÊÍ¿"
Qs(3) = "4) ãÇ åæ Ãæá ãÓÌÏ Ýí ÇáÅÓáÇã¿"
' Set all user answers to negative
For Ctr = 0 To NOOFQS - 1
UserAns(Ctr) = -1
Next Ctr
' All the choices 3 each for a question
Choices(0, 0) = " ÕáÇÍ ÇáÏíä ÇáÃíæÈí"
Choices(0, 1) = " ÇáÞÇÆÏ ÇáãÙÝÑ"
Choices(0, 2) = " ÎÇáÏ Èä ÇáæáíÏ"
Choices(0, 3) = " ÇáÙÇåÑ ÈíÈÑÓ"
Choices(1, 0) = " ÃÓãÇÁ ÈäÊ ÃÈí ÈßÑ "
Choices(1, 1) = " ÓæÏÉ ÈäÊ ÒãÚÉ "
Choices(1, 2) = " ÎÏíÌÉ ÈäÊ ÎæíáÏ "
Choices(1, 3) = " Ãã ÚãÇÑ Èä íÇÓÑ "
Choices(2, 0) = " ØáíØáÉ "
Choices(2, 1) = " ÇáÞÇÏÓíÉ "
Choices(2, 2) = " ÇáÞÓØäØíäíÉ "
Choices(2, 3) = " ÇáÃäÏáÓ"
Choices(3, 0) = " ãÓÌÏ ÞÈÇÁ"
Choices(3, 1) = " ãÓÌÏ Ðí ÇáäæÑíä"
Choices(3, 2) = " ÇáãÓÌÏ ÇáäÈæí"
Choices(3, 3) = " ÇáÈíÊ ÇáÍÑÇã"
' Provide the answer list here.
' Ans(0) = 0 means that the correct answer to the 1st question is the 1st choice.
' Ans(1) = 1 means that the correct answer to the 2nd question is the 2nd choice.
' Ans(2) = 1 means that the correct answer to the 3rd question is the 2nd choice.
Ans(0) = 0
Ans(1) = 2
Ans(2) = 2
Ans(3) = 0
QNo = 1
AssignValues
With SlideShowWindows(1)
.View.GotoSlide (.Presentation.Slides("QSlide").SlideIndex)
End With
' Comment the line below to stop the timer.
Call Tmr
End Sub
Sub SetBulletUnicode(ShapeName As String, Code As Integer)
With SlideShowWindows(1).Presentation.Slides("QSlide").Shapes(ShapeName).TextFrame.TextRange.ParagraphFormat.Bullet
.UseTextFont = msoTrue
.Character = Code
End With
End Sub
Sub ButtonChoice1()
UserAns(QNo - 1) = 0
AssignValues
End Sub
Sub ButtonChoice2()
UserAns(QNo - 1) = 1
AssignValues
End Sub
Sub ButtonChoice3()
UserAns(QNo - 1) = 2
AssignValues
End Sub
Sub Tmr()
'Just in the eventuality that you click the start button twice
'isRunning stores the current state of the macro
'TRUE = Running; FALSE = Idle
ExitFlag = False
Static isRunning As Boolean
If isRunning = True Then
End
Else
isRunning = True
Dim TMinus As Integer
Dim xtime As Date
xtime = Now
With ActivePresentation.Slides(2).Shapes("Timer")
'Countdown in seconds
TMinus = 59
Do While (TMinus > -1)
DoEvents
' Rather crude way to determine if a second has elapsed
If ExitFlag = True Then
.TextFrame.TextRange.Text = "00:00:00"
isRunning = False
Exit Sub
End If
If Format(Now, "ss") <> Format(xtime, "ss") Then
xtime = Now
.TextFrame.TextRange.Text = Format(TimeValue(Format(Now, "hh:mm:ss")) - _
TimeSerial(Hour(Now), Minute(Now), Second(Now) + TMinus), "hh:mm:ss")
TMinus = TMinus - 1
' Let the display refresh itself
End If
Loop
End With
Debug.Print "came here"
isRunning = False
StopQuiz True
End
End If
End Sub
Sub AssignValues()
SetBulletUnicode "Choice1", UD_CODE_1
SetBulletUnicode "Choice2", UD_CODE_1
SetBulletUnicode "Choice3", UD_CODE_1
SetBulletUnicode "Choice4", UD_CODE_1
Select Case UserAns(QNo - 1)
Case 0
SetBulletUnicode "Choice1", UD_CODE_2
Case 1
SetBulletUnicode "Choice2", UD_CODE_2
Case 2
SetBulletUnicode "Choice3", UD_CODE_2
Case 3
SetBulletUnicode "Choice4", UD_CODE_2
End Select
With SlideShowWindows(1).Presentation.Slides("QSlide")
.Shapes(1).TextFrame.TextRange.Text = Qs(QNo - 1)
.Shapes("Choice1").TextFrame.TextRange.Text = Choices(QNo - 1, 0)
.Shapes("Choice2").TextFrame.TextRange.Text = Choices(QNo - 1, 1)
.Shapes("Choice3").TextFrame.TextRange.Text = Choices(QNo - 1, 2)
.Shapes("Choice4").TextFrame.TextRange.Text = Choices(QNo - 1, 3)
End With
End Sub
Sub ShowAnswers()
Dim AnsList As String
AnsList = "The answers are as follows:" & vbCrLf
For X = 0 To NOOFQS - 1
AnsList = AnsList & Qs(X) & vbTab & " Answer:" & Choices(X, Ans(X)) & vbCrLf
Next X
MsgBox AnsList, vbOKOnly, "Correct answers"
End Sub
Related
Here's my problem:
I have a Userform Progress Bar that is intended to update the "% Completed" after each iteration of a For loop. However, when the Userform is clicked, the "% Completed" bar and value increment. I'm not sure why it does this and it appears to be only cosmetic but it's important that the "% Completed" bar and value match the present iteration status.
Is there a way to prevent this from occurring if the window is accidently clicked during the calculation?
Code:
Sub helpme()
Dim x As Long, y As Long, i As Double, j As Double, p As Double, q As Double
Dim max As Integer, max2 As Integer, maxTotal As Integer
Dim pctComp As Single
Dim startTime As Double
Dim runTime As Double
Dim sh As Worksheet
'Error handling for debugging
Dim errorCount As Long
Dim totalErrorCount As Long
x = 11
y = 11
max = InputBox("How many batches are we evaluating?", "Batch Range")
max2 = max
maxTotal = max + max2
For Each sh In Worksheets
Calculate
errorCount = ErrorCheck(sh.Range("A1:ZZ1000"))
If errorCount > 0 Then
MsgBox sh.Name & ": " & errorCount & " " & "error(s)"
End If
totalErrorCount = totalErrorCount + errorCount
Next
MsgBox "There are" & " " & totalErrorCount & " " & "in workbook"
startTime = Timer
runTime = Timer
DoEvents
For i = 4 To max
Application.ScreenUpdating = False
Application.EnableEvents = False
'Calculate
With Sheets("Calc").Cells(3, x + 22).Resize(248, 11)
.Value = Sheets("Calc").Cells(3, 22).Resize(248, 11).FormulaR1C1
End With
x = x + 11
runTime = Timer
pctComp = Round((i / maxTotal) * 100, 1)
Progress pctComp
CalcClock runTime, startTime
Calculate
Application.ScreenUpdating = True
Application.StatusBar = "Calculating Cascade Series I: " & i & " of " & max & ":" & Format(i / max, " " & "0%")
'ClearData.SetText Text:=Empty
'ClearData.PutInClipboard
Next i
For j = 4 To max2
Application.ScreenUpdating = False
Application.EnableEvents = False
'Calculate
With Sheets("Calc2").Cells(3, y + 22).Resize(248, 11)
.Value = Sheets("Calc2").Cells(3, 22).Resize(248, 11).FormulaR1C1
End With
y = y + 11
runTime = Timer
pctComp = Round(((i + j) / maxTotal) * 100, 1)
If pctComp > 100 Then
pctComp = 100
End If
Progress pctComp
CalcClock runTime, startTime
Calculate
Application.ScreenUpdating = True
Application.StatusBar = "Calculating Cascade Series II: " & j & " of " & max2 & ":" & Format(j / max2, " " & "0%")
Next j
Here is the UserForm code:
Private Sub CommandButton1_Click()
Application.ScreenUpdating = True
Application.StatusBar = False
End
End Sub
Private Sub Frame1_Click()
End Sub
Private Sub Text1_Click()
End Sub
Private Sub Text2_Click()
End Sub
Private Sub UserForm_Activate()
helpme
End Sub
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
Application.ScreenUpdating = True
Application.StatusBar = False
End
End Sub
Private Sub UserForm_End()
Application.ScreenUpdating = True
Application.StatusBar = False
Unload.Me
End Sub
I've created 3 combobox as below which are to generate results from a listbox. I would like to generate an error box if any of the 3 comboboxes are left empty. However, the code I wrote generates multiple error msg boxes. How do I fix this so msgbox only appears once?
Private Sub Generateresults_Click()
Dim x As Integer
Dim i As Integer
Dim j As Integer
Dim p As Integer
p = Sheets("Training1A").UsedRange.Rows.Count
Sheets("Results").Range("A2:P" & p).ClearContents
x = 2
For i = 0 To Me.Listtest.ListCount - 1
If Me.Searchoption = "AND" Then
If Me.Listtest.Column(1, i) = Search1 And Me.Listtest.Column(2, i) = Search2 Then
For j = 0 To 9
Sheets("results").Cells(x, j + 1) = Me.Listtest.Column(j, i)
Next j
x = x + 1
Else
x = x
End If
ElseIf Me.Searchoption = "OR" Then
If Me.Listtest.Column(1, i) = Search1 Or Me.Listtest.Column(2, i) = Search2 Then
For j = 0 To 9
Sheets("results").Cells(x, j + 1) = Me.Listtest.Column(j, i)
Next j
x = x + 1
Else
x = x
End If
ElseIf Me.Searchoption = "ALL" Then
For j = 0 To 9
Sheets("results").Cells(x, j + 1) = Me.Listtest.Column(j, i)
Next j
x = x + 1
Else
x = x
**If Searchoption = "" Or Search1 = "" Or Search2 = "" Then
MsgBox "Select an option"
End If**
End If
Next i
End Sub
If you want to bail out after dispaying the first MsgBox, put Exit Sub under it.
If Searchoption = "" Or Search1 = "" Or Search2 = "" Then
MsgBox "Select an option"
Exit Sub
End If
Otherwise, the MsgBox call being inside the For...Next loop body, it will be repeated for every iteration that satisfies the conditions.
If you need to run more code between Next and End Sub regardless of whether the MsgBox was shown or not, then you can also Exit For, to exit the loop but remain inside the procedure:
If Searchoption = "" Or Search1 = "" Or Search2 = "" Then
MsgBox "Select an option"
Exit For
End If
I have made a userform that allows the user to select a table and add rows to it and fill those rows with various information, all from the userform. I have run into a few problems with this.
First after adding or during adding the items (after hitting submit) excel would crash. It occurs randomly and is hard to reproduce.
Second after running the macro there is a good chance that all the cells in the workbook and every other object except the userform button will stop working, meaning you can't edit interact or even select anything. Then when I close the workbook excel crashes after saving. This is my major offender and I think causes the other problem.
What causes this freezing and why does it occur? How do I fix it? I have looked around and haven't found anything circumstantial. One post said that I should try editing the table with no formatting on it and I did that and it didn't work.
I can provide the excel workbook at a request basis via pm.
The code:
On Activate -
Public Sub UserForm_Activate()
Set cBook = ThisWorkbook
Set dsheet = cBook.Sheets("DATA")
End Sub
Help Checkbox -
Private Sub cbHelp_Click()
If Me.cbHelp.Value = True Then
Me.lbHelp.Visible = True
Else
Me.lbHelp.Visible = False
End If
End Sub
Brand combobox -
Public Sub cmbBrand_Change()
brandTableName = cmbBrand.Value
brandTableName = CleanBrandTableName(brandTableName)
'if brand_edit is not = to a table name then error is thrown
On Error Resume Next
If Err = 380 Then
Exit Sub
Else
cmbItemID.RowSource = brandTableName
End If
On Error GoTo 0
'Set cmbItemID's text to nothing after changing to a new brand
cmbItemID.Text = ""
End Sub
CleanBrandTableName(brandTableName) function -
Option Explicit
Public Function CleanBrandTableName(ByVal brandTableName As String) As String
Dim s As Integer
Dim cleanResult As String
For s = 1 To Len(brandTableName)
Select Case Asc(Mid(brandTableName, s, 1))
Case 32, 48 To 57, 65 To 90, 97 To 122:
cleanResult = cleanResult & Mid(brandTableName, s, 1)
Case 95
cleanResult = cleanResult & " "
Case 38
cleanResult = cleanResult & "and"
End Select
Next s
CleanBrandTableName = Replace(WorksheetFunction.Trim(cleanResult), " ", "_")
End Function
Public Function CleanSpecHyperlink(ByVal specLink As String) As String
Dim cleanLink As Variant
cleanLink = specLink
cleanLink = Replace(cleanLink, "=HYPERLINK(", "")
cleanLink = Replace(cleanLink, ")", "")
cleanLink = Replace(cleanLink, ",", "")
cleanLink = Replace(cleanLink, """", "")
cleanLink = Replace(cleanLink, "Specs", "")
CleanSpecHyperlink = cleanLink
End Function
Browse button -
Public Sub cbBrowse_Click()
Dim rPos As Long
Dim lPos As Long
Dim dPos As Long
specLinkFileName = bFile
rPos = InStrRev(specLinkFileName, "\PDFS\")
lPos = Len(specLinkFileName)
dPos = lPos - rPos
specLinkFileName = Right(specLinkFileName, dPos)
Me.tbSpecLink.Text = specLinkFileName
End Sub
bFile function -
Option Explicit
Public Function bFile() As String
bFile = Application.GetOpenFilename(Title:="Please choose a file to open")
If bFile = "" Then
MsgBox "No file selected.", vbExclamation, "Sorry!"
Exit Function
End If
End Function
Preview button -
Private Sub cbSpecs_Click()
If specLinkFileName = "" Then Exit Sub
cBook.FollowHyperlink (specLinkFileName)
End Sub
Add Item button -
Private Sub cbAddItem_Click()
Dim brand As String
Dim description As String
Dim listPrice As Currency
Dim cost As Currency
Dim Notes As String
Dim other As Variant
itemID = Me.tbNewItem.Text
brand = Me.tbBrandName.Text
description = Me.tbDescription.Text
specLink = Replace(specLinkFileName, specLinkFileName, "=HYPERLINK(""" & specLinkFileName & """,""Specs"")")
If Me.tbListPrice.Text = "" Then
listPrice = 0
Else
listPrice = Me.tbListPrice.Text
End If
If Me.tbCost.Text = "" Then
cost = 0
Else
cost = Me.tbCost.Text
End If
Notes = Me.tbNotes.Text
other = Me.tbOther.Text
If Me.lbItemList.listCount = 0 Then
x = 0
End If
With Me.lbItemList
Me.lbItemList.ColumnCount = 8
.AddItem
.List(x, 0) = itemID
.List(x, 1) = brand
.List(x, 2) = description
.List(x, 3) = specLink
.List(x, 4) = listPrice
.List(x, 5) = cost
.List(x, 6) = Notes
.List(x, 7) = other
x = x + 1
End With
End Sub
Submit button -
Private Sub cbSubmit_Click()
Dim n As Long
Dim v As Long
Dim vTable() As Variant
Dim r As Long
Dim o As Long
Dim c As Long
Dim w As Variant
Set brandTable = dsheet.ListObjects(brandTableName)
o = 1
listAmount = lbItemList.listCount
v = brandTable.ListRows.Count
w = 0
For c = 1 To listAmount
If brandTable.ListRows(v).Range(, 1).Value <> "" Then
brandTable.ListRows.Add alwaysinsert:=True
brandTable.ListRows.Add alwaysinsert:=True
Else
brandTable.ListRows.Add alwaysinsert:=True
End If
Next
ReDim vTable(1000, 1 To 10)
For n = 0 To listAmount - 1
vTable(n + 1, 1) = lbItemList.List(n, 0)
vTable(n + 1, 2) = lbItemList.List(n, 1)
vTable(n + 1, 3) = lbItemList.List(n, 2)
vTable(n + 1, 5) = lbItemList.List(n, 4)
vTable(n + 1, 6) = lbItemList.List(n, 5)
vTable(n + 1, 7) = lbItemList.List(n, 6)
vTable(n + 1, 8) = lbItemList.List(n, 7)
If lbItemList.List(n, 3) = "" Then
ElseIf lbItemList.List(n, 3) <> "" Then
vTable(n + 1, 4) = lbItemList.List(n, 3)
End If
If n = 0 And brandTable.DataBodyRange(1, 1) <> "" Then
For r = 1 To brandTable.ListRows.Count
If brandTable.DataBodyRange(r, 1) <> "" Then
o = r + 1
' brandTable.ListRows.Add alwaysinsert:=True
End If
Next
End If
brandTable.ListColumns(1).DataBodyRange(n + o).Value = vTable(n + 1, 1)
brandTable.ListColumns(2).DataBodyRange(n + o).Value = vTable(n + 1, 2)
brandTable.ListColumns(3).DataBodyRange(n + o).Value = vTable(n + 1, 3)
brandTable.ListColumns(4).DataBodyRange(n + o).Value = vTable(n + 1, 4)
brandTable.ListColumns(5).DataBodyRange(n + o).Value = vTable(n + 1, 5)
brandTable.ListColumns(6).DataBodyRange(n + o).Value = vTable(n + 1, 6)
brandTable.ListColumns(7).DataBodyRange(n + o).Value = vTable(n + 1, 7)
brandTable.ListColumns(8).DataBodyRange(n + o).Value = vTable(n + 1, 8)
Next
brandTable.DataBodyRange.Select
Selection.Font.Bold = True
Selection.WrapText = True
brandTable.ListColumns(5).DataBodyRange.Select
Selection.NumberFormat = "$#,##0.00"
brandTable.ListColumns(6).DataBodyRange.Select
Selection.NumberFormat = "$#,##0.00"
Unload Me
End Sub
Remove Items button -
Private Sub cbRemoveItems_Click()
Dim intCount As Long
For intCount = lbItemList.listCount - 1 To 0 Step -1
If lbItemList.Selected(intCount) Then
lbItemList.RemoveItem (intCount)
x = x - 1
End If
Next intCount
End Sub
There is other code that does things for the other tabs but they don't interact with this tabs code.
I am using excel 2007, ms visual basic 6.0.
I required to check the window os date format (e.g, whether is it using d/m/yyyy or m/d/yyyy), in order to using the following code.
Dim lastdateofmonth As Date
Dim lastwhichday As String
slastdayofmonth = "31"
'if the OS system is using m/d/yyyy then use this
lastdateofmonth = (sTxtMMM + "/" + slastdayofmonth + "/" + TxtYYYY)
lastwhichday = Weekday(lastdateofmonth)
'if th OS system is using d/m/yyyy then use this
lastdateofmonth = (slastdayofmonth+ "/" + sTxtMMM + "/" + TxtYYYY)
anyone can help? Thanks in advance
hmm... i found a better way
'========== Check OS Date format========
Dim OSDateFormatType As Integer
' 0 = month-day-year; 1 = day-month-year; 2 = year-month-day
If Application.International(xlDateOrder) = 0 Then
OSDateFormatType = 0
ElseIf Application.International(xlDateOrder) = 1 Then
OSDateFormatType = 1
ElseIf Application.International(xlDateOrder) = 2 Then
OSDateFormatType = 2
End If
But this only work for excel.
Check below code....
Sub getSystemDateFormat()
Application.AskToUpdateLinks = False
Application.DisplayAlerts = False
If isSheetExists(ThisWorkbook, "Temp") = False Then
ThisWorkbook.Sheets.Add After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count)
ThisWorkbook.ActiveSheet.Name = "Temp"
End If
ThisWorkbook.Sheets("Temp").Cells(1, 1) = ""
'On Error GoTo ErrHandle
'Get Date format
lngDateFormat = Application.International(xlDateOrder)
'Get Date Separator
strDateSeparator = Application.International(xlDateSeparator)
'Get leading 0 for day
If Application.International(xlDayLeadingZero) Then
strDayFormat = "dd"
Else
strDayFormat = "d"
End If
'Get leading 0 for month
If Application.International(xlMonthLeadingZero) Then
strMonthFormat = "mm"
Else
strMonthFormat = "m"
End If
'Get 4 digit/2 digit format for year
If Application.International(xl4DigitYears) Then
strYearFormat = "yyyy"
Else
strYearFormat = "yy"
End If
'Consolidate the values
If lngDateFormat = 0 Then ' Month-Day-Year
lngPos1 = InStr(1, Now(), strDateSeparator)
If lngPos1 = 4 Then
strMonthFormat = "mmm"
End If
strDateFormat = strMonthFormat & strDateSeparator & strDayFormat & strDateSeparator & strYearFormat
ElseIf lngDateFormat = 1 Then ' Day-Month-Year
lngPos1 = InStr(1, Now(), strDateSeparator)
lngPos2 = InStr(lngPos1 + 1, Now(), strDateSeparator)
If lngPos2 - lngPos1 = 4 Then
strMonthFormat = "mmm"
End If
strDateFormat = strDayFormat & strDateSeparator & strMonthFormat & strDateSeparator & strYearFormat
Else ' Year-Month-Day
lngPos1 = InStr(1, Now(), strDateSeparator)
lngPos2 = InStr(lngPos1 + 1, Now(), strDateSeparator)
If lngPos2 - lngPos1 = 4 Then
strMonthFormat = "mmm"
End If
strDateFormat = strYearFormat & strDateSeparator & strMonthFormat & strDateSeparator & strDayFormat
End If
MsgBox strDateFormat
EndLine:
ThisWorkbook.Sheets("Temp").Activate
ThisWorkbook.Sheets("Temp").Cells(1, 1) = strDateFormat
Exit Sub
ErrHandle:
If Err.Description <> "" Then
ThisWorkbook.Sheets("Temp").Cells(1, 1) = Err.Description
End If
ThisWorkbook.Sheets("Temp").Activate
End Sub
Function isSheetExists(wbk As Workbook, strSheetName As String) As Boolean
isSheetExists = False
For i = 1 To wbk.Sheets.Count
If wbk.Sheets(i).Name = strSheetName Then
isSheetExists = True
Exit For
End If
Next i
End Function
The best way:
if Application.International(xlMDY) then ...
True - month, day, year
False - day, month, year
https://msdn.microsoft.com/en-us/library/office/ff840213%28v=office.15%29.aspx
I would like to filter a Listbox created from a list of values stored in a worksheet depending on text written in a textbox contained in the same userform.
My Listbox has 4 or 5 columns (depending on OptionField selection) and I would like to search all the columns for the text written.
Example: I write "aaa" in TextField and the Listbox should return a list based on all the lines whose column 1 or 2 or 3 or 4 or 5 contain "aaa".
Below my code to refresh the list on OptionField selection (this code does not produce any error, it is just to show how I create my list):
Sub RefreshList()
Dim selcell, firstcell As String
Dim k, i As Integer
Dim r as long
i = 0
k = 0
' reads parameters from hidden worksheet
If Me.new_schl = True Then
firstcell = Cells(3, 4).Address
selcell = firstcell
Do Until IsEmpty(Range("" & selcell & "")) And i = 2
If IsEmpty(Range("" & selcell & "")) Then i = i + 1
k = k + 1
selcell = Cells(1 + k, 7).Address(0, 0)
Loop
k = k - 1
selcell = Cells(1 + k, 7).Address(0, 0)
With Me.ListBox1
.ColumnCount = 4
.ColumnWidths = "50; 80; 160; 40"
.RowSource = ""
Set MyData = Range("" & firstcell & ":" & selcell & "")
.List = MyData.Cells.Value
For r = .ListCount - 1 To 0 Step -1
If .List(r, 3) = "" Or .List(r, 3) = "0" Then
.RemoveItem r
End If
Next r
End With
Else
firstcell = Cells(3, 11).Address
selcell = firstcell
Do Until IsEmpty(Range("" & selcell & "")) And i = 11
If IsEmpty(Range("" & selcell & "")) Then i = i + 1
k = k + 1
selcell = Cells(1 + k, 15).Address(0, 0)
Loop
k = k - 1
selcell = Cells(1 + k, 15).Address(0, 0)
With Me.ListBox1
.ColumnCount = 5
.ColumnWidths = "40; 40; 160; 40; 40"
.RowSource = ""
Set MyData = Range("" & firstcell & ":" & selcell & "")
.List = MyData.Cells.Value
For r = .ListCount - 1 To 0 Step -1
If .List(r, 3) = "" Or .List(r, 3) = "0" Then
.RemoveItem r
End If
Next r
End With
End If
End Sub
Finally I could come out with something!
Sub Filter_Change()
Dim i As Long
Dim Str As String
Str = Me.Filter.Text
Me.RefreshList
If Not Str = "" Then
With Me.ListBox1
For i = .ListCount - 1 To 0 Step -1
If InStr(1, LCase(.List(i, 0)), LCase(Str)) = 0 And InStr(1, LCase(.List(i, 1)), LCase(Str)) = 0 And _
InStr(1, LCase(.List(i, 2)), LCase(Str)) = 0 And InStr(1, LCase(.List(i, 3)), LCase(Str)) = 0 Then
.RemoveItem i
End If
Next i
End With
End If
End Sub
I know, the answer is couple of years old...
But I thought I'd share solution that works the best for me, because the filter is blazing fast even when there are thousands of items in the list. It is not without a "catch", though:
it uses a Dictionary object
Option Explicit
Dim myDictionary As Scripting.Dictionary
Private Sub fillListbox()
Dim iii As Integer
Set myDictionary = New Scripting.Dictionary
' this, here, is just a "draft" of a possible loop
' for filling in the dictionary
For iii = 1 To RANGE_END
If Not myDictionary.Exists(UNIQUE_VALUE) Then
myDictionary.Add INDEX, VALUE
End If
Next
myListbox.List = myDictionary .Items
End Sub
Private Sub textboxSearch_Change()
Dim Keys As Variant
Keys = myDictionary .Items
myListbox.List = Filter(Keys, textboxSearch.Text, True, vbTextCompare)
End Sub
Private Sub UserForm_Initialize()
Call fillListbox
End Sub