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
Related
i am receiving run-time error "424" Object required when trying to run the following vba script code within excel.
The error is occuring at the line of code:
For x = 0 To Rs.Fields.Count - 1
I have no clue why this is happening. This is code that was sent to me from someone else and no longer is using SQL as the data source, just referencing data already pasted to the Combined Data sheet.
Sub getInfo()
Dim sProvider As String
Dim strSQL As String
Dim JanRange, FebRange, MarRange, AprRange, MayRange, JunRange, TargetRange As Range
Dim JulRange, AugRange, SepRange, OctRange, NovRange, DecRange, SumRange As Range
Dim Sht As Worksheet
Dim newSht As Worksheet
Dim comSht As Worksheet
Dim x As Integer
Dim LastMonthYear As Integer
Dim comLastRow As Integer
Application.DisplayAlerts = False
Set Sht = ThisWorkbook.Sheets("Over View")
Set comSht = ThisWorkbook.Sheets("Combined Data")
Set JanRange = Sht.Range("A2:B17")
Set FebRange = Sht.Range("E2:F17")
Set MarRange = Sht.Range("A20:B35")
Set AprRange = Sht.Range("E20:F35")
Set MayRange = Sht.Range("A37:B52")
Set JunRange = Sht.Range("E37:F52")
Set JulRange = Sht.Range("A54:B69")
Set AugRange = Sht.Range("E54:F69")
Set SepRange = Sht.Range("A71:B86")
Set OctRange = Sht.Range("E71:F86")
Set NovRange = Sht.Range("A88:B103")
Set DecRange = Sht.Range("E88:F103")
Set SumRange = Sht.Range("I2:J17")
'Setting Year equal to year of last month
If Month(Date) = 1 Then
LastMonthYear = Year(Date) - 1
Else
LastMonthYear = Year(Date)
End If
'Adding a new sheet after the first sheet
Set newSht = ThisWorkbook.Worksheets.Add
newSht.Move after:=Worksheets("Over View")
newSht.Name = MonthName(Month(DateAdd("m", -1, Date))) & " " & LastMonthYear & " Data"
'Get the column names from the recordset to put at the top of the spreadsheet
For x = 0 To Rs.Fields.Count - 1
newSht.Cells(1, x + 1).Value = Rs.Fields(x).Name
Next
'Copying the recordset to the new sheet, then deleting some unneccessary columns, formatting columns, etc
With newSht
.Range("A2").CopyFromRecordset Rs
.Columns("AP").Delete
.Columns("O:R").Delete
.Columns("B").Delete
.Columns("D:G").NumberFormat = "M/D/YYYY"
.Columns("L:M").NumberFormat = "#,##0"
.Columns("N:AG").NumberFormat = "#,##0.00"
.Rows(1).Font.Bold = True
.UsedRange.Columns.AutoFit
'Getting the last row of the combined sheet and then pasting the new information to the combined sheet
comLastRow = comSht.UsedRange.Rows.Count
.Range("A2:AJ" & .UsedRange.Rows.Count).Copy comSht.Range("A" & comLastRow + 1)
End With
Rs.Close
cn.Close
'Calculating Combined Numbers on Main Sheet
Sht.Range("J3").Formula = "=COUNTA('Combined Data'!$B:$B)-1"
Sht.Range("J4").Formula = "=SUM('Combined Data'!$O:$O) / SUM('Combined Data'!$L:$L)"
Sht.Range("J5").Formula = "=SUM('Combined Data'!$P:$P) / SUM('Combined Data'!$L:$L)"
Sht.Range("J6").Formula = "=SUM('Combined Data'!$R:$R) / SUM('Combined Data'!$L:$L)"
Sht.Range("J7").Formula = "=SUM('Combined Data'!$N:$N) / SUM('Combined Data'!$L:$L)"
Sht.Range("J8").Formula = "=SUM('Combined Data'!$O:$O) / J3"
Sht.Range("J9").Formula = "=SUM('Combined Data'!$P:$P) / J3"
Sht.Range("J10").Formula = "=SUM('Combined Data'!$R:$R) / J3"
Sht.Range("J11").Formula = "=J12/J3"
Sht.Range("J12").Formula = "=SUM('Combined Data'!$N:$N)"
Sht.Range("J13").Formula = "=SUM('Combined Data'!$N:$N) / SUM('Combined Data'!$M:$M)"
Sht.Range("J14").Formula = "=SUM('Combined Data'!$M:$M) / J3"
Sht.Range("J15").Formula = "=SUM('Combined Data'!$L:$L) / J3"
Sht.Range("J16").Formula = "=SUM('Combined Data'!$AJ:$AJ)"
Sht.Range("J17").Formula = "=J16/J3"
'Selecting the range for the new month based on what month last month was
Select Case Month(DateAdd("m", -1, Date))
Case 1
Set TargetRange = JanRange
Case 2
Set TargetRange = FebRange
Case 3
Set TargetRange = MarRange
Case 4
Set TargetRange = AprRange
Case 5
Set TargetRange = MayRange
Case 6
Set TargetRange = JunRange
Case 7
Set TargetRange = JulRange
Case 8
Set TargetRange = AugRange
Case 9
Set TargetRange = SepRange
Case 10
Set TargetRange = OctRange
Case 11
Set TargetRange = NovRange
Case 12
Set TargetRange = DecRange
End Select
'Setting this value on overall summary to copy it then once copied set it back to range. Also temporarily changing header highlight color
Sht.Range("I2").Value = MonthName(Month(DateAdd("m", -1, Date))) & " " & Year(DateAdd("m", -1, Date)) & " Metrics"
Sht.Range("I2:J2").Interior.ThemeColor = xlThemeColorAccent1
'Copies the formatting from the Orange Summary table to the new area for formatting and such
SumRange.Copy TargetRange
'Replaces the Sheet name Combined Data with the sheet name of the new sheet in all the formulas
TargetRange.Replace What:="Combined Data", Replacement:=MonthName(Month(DateAdd("m", -1, Date))) & " " & Year(DateAdd("m", -1, Date)) & " Data"
Sht.Range("I2").Value = Replace(Sht.Range("A2").Value, " Metrics", "") & " Through " & MonthName(Month(DateAdd("m", -1, Date))) & " " & Year(DateAdd("m", -1, Date))
Sht.Range("I2:J2").Interior.ThemeColor = xlThemeColorAccent4
'Cleaning out tables and data if it is January of new Year
If Month(DateAdd("m", -1, Date)) = 1 Then
Sht.Range("A19:F200").ClearContents
Sht.Range("A19:F200").ClearFormats
Sht.Range("E1:F18").ClearContents
Sht.Range("E1:F18").ClearFormats
x = 2
comLastRow = comSht.UsedRange.Rows.Count
While x <= comLastRow
If comSht.Range("E" & x).Value < DateAdd("d", -Day(Date) + 1, DateAdd("m", -1, Date)) Then
comSht.Cells(x, 1).EntireRow.Delete
comLastRow = comLastRow - 1
x = x - 1
End If
x = x + 1
Wend
'If February then deleting all of the sheets except Over View and January tab
Dim wSht As Worksheet
For Each wSht In ThisWorkbook.Worksheets
If wSht.Name <> "Over View" And wSht.Name <> "Combined Data" And wSht.Name <> MonthName(Month(DateAdd("m", -1, Date))) & " " & LastMonthYear & " Data" Then
wSht.Delete
End If
Next
End If
Sht.Activate
Sht.Cells(1, 1).Select
ThisWorkbook.Save
If Month(DateAdd("m", -1, Date)) = 1 Then
ThisWorkbook.SaveAs "C:\Users\Connor.Osborne\Desktop\alex work project " & LastMonthYear & " Data.xlsx", xlWorkbookDefault
Else
ThisWorkbook.SaveAs "C:\Users\Connor.Osborne\Desktop\alex work project" & "-" & MonthName(Month(DateAdd("m", -1, Date)), True) & " " & LastMonthYear & " Data.xlsx", xlWorkbookDefault
End If
ThisWorkbook.Saved = True
Application.DisplayAlerts = True
If Application.Workbooks.Count = 1 Then
Application.Quit
Else
ThisWorkbook.Close
End If
Exit Sub
ThisWorkbook.Saved = True
If Application.Workbooks.Count = 1 Then
Application.Quit
Else
ThisWorkbook.Close
End If
End Sub
This code will output individual sheets from the combined data sheet, as well as create a summary sheet with certain calculations.
I hope some of you can help with the code under these text, I can export Attachments which are in the body of an Lotus Notes Mail, but also I need to export them, when they aren't in the body (like "normal" attachments).
Set LNItem = doc.GETFIRSTITEM("Body")
If doc.HasEmbedded Then
int_Anhang = 1
x = 0
Worksheets("Mails").Cells(j, 3).Value = 0
On Error Resume Next
For Each LNAttachment In LNItem.EmbeddedObjects
y = 0
AttPath = ActiveWorkbook.path & "1-Weiterleitung_Mail-Anhang" & y & "-" + LNAttachment.Name
While Dir(AttPath) <> ""
y = y + 1
AttPath = ActiveWorkbook.path & "1-Weiterleitung_Mail-Anhang" & y & "-" + LNAttachment.Name
Wend
LNAttachment.ExtractFile (AttPath)
Worksheets("Mails").Cells(j, 3).Value = Worksheets("Mails").Cells(j, 3).Value + 1
Worksheets("Mails").Cells(j, 7 + x).Value = y & "-" + LNAttachment.Name
x = x + 1
Next
On Error GoTo Fehler
Debug.Print vbNewLine
End If
Can someone help?
My Question in other communities:
ms-office-forum.net
Herber.de
Here are more code:
Dim sess As Object, db As Object, folder As Object, dc As Object, docMemo As Object, docNext As Object, LNItem As Object
Dim memoSenders As Variant, memoAnhang As Variant, memoInhalt As Variant, memoLayout As Variant, LNAttachment As Variant
Dim memoDate As Date, todayDate As Date
Dim mail_Server As String, mail_Datei As String, memoSubject As String, AttPath As String
Dim y As Integer, int_test As Integer
'On Error GoTo Fehler_Notes
On Error GoTo Fehler
Set sess = CreateObject("Notes.NotesSession")
'sess.Initialize ("")
'On Error GoTo Fehler
mail_Server = Worksheets("Daten").Cells(2, 2).Value
mail_Datei = Worksheets("Daten").Cells(2, 3).Value
'Open the mail database in notes
Set db = sess.GetDatabase(mail_Server, mail_Datei)
If db.IsOpen = True Then
'Already open for mail
Else
db.OPENMAIL
End If
int_test = 0
Do While Worksheets("Daten").Cells(i, 6).Value <> ""
Set folder = db.GetView(Worksheets("Daten").Cells(i, 6).Value)
If Worksheets("Daten").Cells(i, 9).Value <> "" Then
todayDate = Worksheets("Daten").Cells(i, 9).Value
Else
Worksheets("Daten").Cells(i, 9).Value = "01.01.2000 00:00"
todayDate = Worksheets("Daten").Cells(i, 9).Value
End If
Set doc = folder.GetFirstDocument
Do Until doc Is Nothing
Set docNext = folder.GetNextDocument(doc)
'Datum des Empfangs
Worksheets("Daten").Cells(29, 2).Value = doc.GetItemValue("DeliveredDate")
memoDate = Worksheets("Daten").Cells(29, 2).Value
int_test = int_test + 1
int_xxx = int_xxx + 1
memoSenders = doc.GetItemValue("From")
memoInhalt = doc.GetItemValue("Body")
memoLayout = doc.GetItemValue("Form")
memoSubject = doc.GetItemValue("Subject")(0)
Worksheets("Mails").Cells(j, 1).Value = i - 2
Worksheets("Mails").Cells(j, 2).Value = memoSenders
Worksheets("Mails").Cells(j, 4).Value = memoInhalt
Worksheets("Mails").Cells(j, 5).Value = memoLayout
Worksheets("Mails").Cells(j, 6).Value = memoSubject
'Prüfen ob Attachments innerhalb der Mail vorhanden sind
Set LNItem = doc.GETFIRSTITEM("Body")
If doc.HasEmbedded Then
int_Anhang = 1
x = 0
Worksheets("Mails").Cells(j, 3).Value = 0
On Error Resume Next
For Each LNAttachment In doc.EmbeddedObjects
y = 0
AttPath = ActiveWorkbook.path & "\01-Weiterleitung_Mail-Anhang\" & y & "-" + LNAttachment.Name
While Dir(AttPath) <> ""
y = y + 1
AttPath = ActiveWorkbook.path & "\01-Weiterleitung_Mail-Anhang\" & y & "-" + LNAttachment.Name
Wend
LNAttachment.ExtractFile (AttPath)
Worksheets("Mails").Cells(j, 3).Value = Worksheets("Mails").Cells(j, 3).Value + 1
Worksheets("Mails").Cells(j, 7 + x).Value = y & "-" + LNAttachment.Name
x = x + 1
Next
On Error GoTo Fehler
Debug.Print vbNewLine
End If
Call doc.PutInFolder(Worksheets("Daten").Cells(6, 3).Value)
Call doc.MarkRead
Call doc.RemoveFromFolder(Worksheets("Daten").Cells(i, 6).Value)
j = j + 1
Set doc = docNext
Loop
Worksheets("Daten").Cells(i, 9).Value = CStr(Format(Now, "MM/DD/YYYY hh:mm"))
i = i + 1
Loop
If int_test <> 0 Then
i = 3
ReadNotesEmail i, j
End If
int_error = 0
Exit Sub
Regards
NotesDocument has also a property EmbeddedObjects.
You can use it this way:
For Each LNAttachment In doc.EmbeddedObjects
...
Next
I've try to make the code from Duston work in Excel VBA:
Set Item = Doc.GetFirstItem("$file")
If LCase(Item.Name) = "$file" Then
Set FileItem = Item
FileName = FileItem.Values(0)
Set Object = Doc.GetAttachment(FileName)
AttPath = ActiveWorkbook.path & "\01-Weiterleitung_Mail-Anhang\" & "1" & "-"
' extract the file ..
Call Object.ExtractFile(AttPath & FileName)
End If
My code produce no error and the script goes into the If-Case, but nothing happens. (The "Filename" is empty)
check for File name and you can get the embededobject
this is the java code:
String path="";
Vector fileName= session.evaluate("#AttachmentNames", document);
for (int i = 0; i < fileName.size(); i++) {
EmbeddedObject embeddedObject =
document.getAttachment(fileName.get(i));
embeddedObject .extractFile(path+fileName.get(i));
}
Also check for items named $File. Some sample code is located in this link:
http://www.richardcivil.net/archives/157
In particular:
If Lcase( item.Name ) = "$file" Then
' get the filename ...
Set FileItem = Item
FileName = FileItem.Values(0)
Set Object = sourceDoc.GetAttachment( FileName )
' extract the file ..
Call object.ExtractFile( tempDir & FileName )
' upload the file ..
Set newObject = attachmentBody.EmbedObject( object.Type, "", tempDir & FileName )
' kill the file ..
Kill tempDir & FileName
End If
So, I'm having some problems with dates that are reversing themselves in VBA when assigned to a Date variable. It's simpler than it sounds, but it's really bugging me.
Code:
Dim InsertedDate as Date
On Error Resume Next
InsertedDate = Me.BoxDate.Value
If InsertedDate = 0 Then
'Do Something
Else
'Do Something Different
End If
So let's assume that user types a value like
12/18/2017
I'm brazilian, so that means the user typed the 12th day of the 18th month. Since there's no 18th month in the year, the user shouldn't be able to type that date and InsertedDate should be equal to 0, right? Or not? I mean, I'm not really sure how Excel work dates.
Anyway, what happens is: Excel automatically reverses the date to
18/12/2017 'InsertedDate Value
instead of InsertedDate being
12/18/2017 'InsertedDate Value
And the code goes to 'Do Something Different. So, how do I solve this? Notice that I haven't assigned the variable value to anything. The process of reversion happens automatically when assigning the value to the variable. I've already tried
Format(InsertedDate, "dd/mm/yyyy") 'Did not work
and
InsertedDate = CDate(Me.BoxDate.Value) 'Did not work
and I tried converting the values in other variables and stuff. So, I'm lost. If anyone could help me, I'd be extremely grateful. Thank you in advance.
If you choose data type as Date it will automatically convert dates to american format.
My suggestion is to check the date format of the user and assume he uses the same (and it is not the safest assumption):
If Application.International(xlMDY) then
InsertedDate = Me.BoxDate.Value
Else:
Arr = Split(Me.BoxDate.Value,"/")
InsertedDate = DateSerial(Arr(2),Arr(1),Arr(0))
End if
But it assumes that user has used "/" as a delimite - and there could be a lot of other scenarios. You can use a date picker instead or a function that will validate the date.
EDIT:
Actually here is a variation of function I use and its implementation in your code:
Sub TestDate()
If ConformDate(Me.BoxDate.Value) = "" Then
MsgBox "Invalid Date!"
Else
MsgBox "" & ConformDate(Me.BoxDate.Value) & " is a valid date"
End If
End Sub
Function ConformDate(DataToTransform As String) As String
Dim DTT As String
Dim delim As String
Dim i As Integer
DTT = DataToTransform
DTT = Trim(DTT)
With CreateObject("VBScript.RegExp")
.Pattern = "\s+"
.Global = True
DTT = .Replace(DTT, " ")
End With
Select Case True
Case (DTT Like "*/*/*")
delim = "/"
Case (DTT Like "*-*-*")
delim = "-"
Case (DTT Like "*.*.*")
delim = "."
Case (DTT Like "* * *")
delim = " "
Case Else
ConformDate = ""
Exit Function
End Select
Arr = Split(DTT, delim)
If UBound(Arr) < 2 Then
ConformDate = ""
Exit Function
End If
Dim Arrm(2) As String
If Application.International(xlMDY) Then
Arrm(0) = Arr(0)
Arrm(1) = Arr(1)
Arrm(2) = Arr(2)
Else
Arrm(0) = Arr(1)
Arrm(1) = Arr(0)
Arrm(2) = Arr(2)
End If
For i = LBound(Arrm) To UBound(Arrm)
If Not IsNumeric(Arrm(i)) Then
ConformDate = ""
Exit Function
End If
Select Case i
Case 0
' Month
If Len(Arrm(i)) < 1 Or Len(Arrm(i)) > 2 Then
ConformDate = ""
Exit Function
End If
If Left(Arrm(i), 1) = "0" And Len(Arrm(i)) = 1 Then
ConformDate = ""
Exit Function
End If
If Left(Arrm(i), 1) = "0" Then Arr(i) = Right(Arrm(i), 1)
If Arrm(i) > 12 Then
ConformDate = ""
Exit Function
End If
Case 1
' Day
If Len(Arrm(i)) < 1 Or Len(Arrm(i)) > 2 Then
ConformDate = ""
Exit Function
End If
If Left(Arrm(i), 1) = "0" And Len(Arrm(i)) = 1 Then
ConformDate = ""
Exit Function
End If
If Left(Arrm(i), 1) = "0" Then Arrm(i) = Right(Arrm(i), 1)
If Arrm(i) > 31 Then
ConformDate = ""
Exit Function
End If
Case 2
' Year
If Not (Len(Arrm(i)) = 2 Or Len(Arrm(i)) = 4) Then
ConformDate = ""
Exit Function
End If
If Len(Arrm(i)) = 2 Then Arrm(i) = Left(Year(Date), 2) & CStr(Arrm(i))
End Select
Next
If Application.International(xlMDY) Then
ConformDate = Format((DateSerial(CInt(Arrm(2)), CInt(Arrm(0)), CInt(Arrm(1)))), "dd/mm/yyyy")
Else
ConformDate = Format((DateSerial(CInt(Arrm(2)), CInt(Arrm(1)), CInt(Arrm(0)))), "dd/mm/yyyy")
End If
End Function
I just could think of a way to make it on the hardest way, which is extracting each element and comparing.
diamesano = Me.BoxDate.Value
'diamesano = "12/18/2017"
dia = CLng(Left(diamesano, 2))
mes = CLng(Left(Mid(diamesano, 4), 2))
ano = CLng(Right(diamesano, 4)) 'Assuming year with 4 digits, otherwise some tweaks are necessary
Debug.Print "day: " & dia & " month: " & mes & " Year: " & ano
date_error = 0
If mes >= 1 And mes <= 12 Then 'Check if month is ok
mesAno = (Right(diamesano, 7))
DiasNoMes = Day(DateSerial(Year(mesAno), Month(mesAno) + 1, 0))
If dia >= 1 And dia <= DiasNoMes Then 'Check the amount of days on this month and if is in range
Debug.Print "OK"
'Do something because the Date is valid!
Else
date_error = 1
End If
Else
date_error = 1
End If
If date_error = 1 Then
Debug.Print "NOK"
'Date is invalid =P
End If
Tried to use IsDate() function, but it reversed the date, even if formatting "dd/mm/yyyy" is used before.
Edit:
UDF to split the date
If the user input another format as "d/m/yy", the code below will correct. In which the function EXTRACTELEMENT will split the String by / and get the elements.
Function EXTRACTELEMENT(Txt As String, n, Separator As String) As String
On Error GoTo ErrHandler:
EXTRACTELEMENT = Split(Application.Trim(Mid(Txt, 1)), Separator)(n - 1)
Exit Function
ErrHandler:
' error handling code
MsgBox "ERROR: Verify if the data exists, example if the separator is correct."
On Error GoTo 0
End Function
So to use the UDF, if the date is diamesano = "2/5/14"
the day will be EXTRACTELEMENT(CStr(diamesano), 1, "/") where 1 is the 1st element that is the value 2
the month will be EXTRACTELEMENT(CStr(diamesano), 2, "/") where 2 is the 2nd element that is the value 5
the year will be EXTRACTELEMENT(CStr(diamesano), 3, "/") where 3 is the 3rd element that is the value 14
Code to use the UDF and check dates
And the code changes to:
diamesano = "12/18/2017"
dia = CLng(EXTRACTELEMENT(CStr(diamesano), 1, "/"))
mes = CLng(EXTRACTELEMENT(CStr(diamesano), 2, "/"))
ano = CLng(EXTRACTELEMENT(CStr(diamesano), 3, "/"))
Debug.Print "day: " & dia & " month: " & mes & " Year: " & ano
date_error = 0
If mes >= 1 And mes <= 12 Then 'Check if month is ok
mesAno = mes & "/" & ano
DiasNoMes = Day(DateSerial(Year(mesAno), Month(mesAno) + 1, 0))
If dia >= 1 And dia <= DiasNoMes Then 'Check the amount of days on this month and if is in range
Debug.Print "OK"
'Do something because the Date is valid!
Else
date_error = 1
End If
Else
date_error = 1
End If
If date_error = 1 Then
Debug.Print "NOK"
'Date is invalid =P
End If
Create UDF to check if the Date is right
Function IsDateRight(diamesano) As String
On Error GoTo ErrHandler:
dia = CLng(Split(Application.Trim(Mid(CStr(diamesano), 1)), "/")(0))
mes = CLng(Split(Application.Trim(Mid(CStr(diamesano), 1)), "/")(1))
ano = CLng(Split(Application.Trim(Mid(CStr(diamesano), 1)), "/")(2))
'Debug.Print "day: " & dia & " month: " & mes & " Year: " & ano
date_error = 0
If mes >= 1 And mes <= 12 Then 'Check if month is ok
mesAno = mes & "/" & ano
DiasNoMes = Day(DateSerial(Year(mesAno), Month(mesAno) + 1, 0))
If dia >= 1 And dia <= DiasNoMes Then 'Check the amount of days on this month and if is in range
IsDateRight = "Yes"
'Do something because the Date is valid!
Else
date_error = 1
End If
Else
date_error = 1
End If
If date_error = 1 Then
IsDateRight = "No"
'Date is invalid =P
End If
Exit Function
ErrHandler:
' error handling code
MsgBox "ERROR: Verify if the data exists, example if the separator is correct."
On Error GoTo 0
End Function
And a test:
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
I have a Word table containing Legacy DropDown List. There is 11 rows and let's say 4 columns. Each cell contains a Legacy DropDown List which puts the count to 11 per column (44 total).
I have to take the data from these Legacy DropDown List and put it into Labels in another table on another page of the same document.
No problem so far, I made it work though I had to do write it all down instead of using a loop because I couldn't find a way to put a variable in my label name.
I shortened my code to only the first row of the first week (therefore 4 labels) because otherwise it would have been too long and there is no need for it to be that way.
Current code :
Sub Week1()
'Week 1
If ActiveDocument.FormFields("Dom1").DropDown.ListEntries.Count <> 0 And ActiveDocument.FormFields("Dom1").DropDown.ListEntries.Item(ActiveDocument.FormFields("Dom1").DropDown.Value).Name <> "Choose a DOM." Then
lblDom1W1.Caption = ActiveDocument.FormFields("Dom1").DropDown.ListEntries.Item(ActiveDocument.FormFields("Dom1").DropDown.Value).Name
End If
If ActiveDocument.FormFields("Sit1").DropDown.ListEntries.Count <> 0 Then
If ActiveDocument.FormFields("Sit1").DropDown.Value <> 0 Then
If ActiveDocument.FormFields("Sit1").DropDown.ListEntries.Item(ActiveDocument.FormFields("Sit1").DropDown.Value).Name <> "Choose a SIT" Then
lblSit1W1.Caption = ActiveDocument.FormFields("Sit1").DropDown.ListEntries.Item(ActiveDocument.FormFields("Sit1").DropDown.Value).Name
End If
End If
End If
If ActiveDocument.FormFields("Int1").DropDown.ListEntries.Count <> 0 Then
If ActiveDocument.FormFields("Int1").DropDown.Value <> 0 Then
lblInt1W1.Caption = ActiveDocument.FormFields("Int1").DropDown.ListEntries.Item(ActiveDocument.FormFields("Int1").DropDown.Value).Name
End If
End If
If ActiveDocument.FormFields("Gram1").DropDown.ListEntries.Count <> 0 And ActiveDocument.FormFields("Gram1").DropDown.ListEntries.Item(ActiveDocument.FormFields("Gram1").DropDown.Value).Name <> "Choose a GRAM." Then
lblGram1W1.Caption = ActiveDocument.FormFields("Gram1").DropDown.ListEntries.Item(ActiveDocument.FormFields("Gram1").DropDown.Value).Name
End If
So this works. That being said, I would like to loop it so I could have this much code only once instead of having it repeated 11 times per week for 11 weeks.
I already named the labels for them to be easy with a loop. Therefore, their names are all lblDom1W1 down to lblDom11W1 for the first week and so on for the other labels (only the last digit changes ( e.i. lblDom1W2 down to lblDom11W2)).
Furthermore, I thought and tried these methods which I thought wouldn't work and didn't :
labelName & value
labelName(value)
I looked through this post but I didn't quite understood everything in it and I'm not sure if that's what I need since it's VB.NET and no exactly VBA. Post I checked
EDIT:
Following user R3uK comment, I tried this but it doesn't work either. I gives me the Invalid qualifier for my leLabelDom.Caption...:
Sub Week1()
'Week1
Dim labelDom As String
labelDom = "lblDom"
Dim week1 As String
week1 = "W1"
Dim leLabelDom As String
For k = 1 To 11
leLabelDom = labelDom & k & week1
If ActiveDocument.FormFields("ListeDomaine" & k).DropDown.ListEntries.Count <> 0 And ActiveDocument.FormFields("ListeDomaine" & k).DropDown.ListEntries.Item(ActiveDocument.FormFields("ListeDomaine" & k).DropDown.Value).Name <> "Choisissez un domaine." Then
leLabelDom.Caption = ActiveDocument.FormFields("ListeDomaine" & k).DropDown.ListEntries.Item(ActiveDocument.FormFields("ListeDomaine" & k).DropDown.Value).Name
End If
EDIT 2 - Working:
Started from the user R3uK answer and end up with this code which works. Huge thanks to you R3uK !
Sub Remplir()
Dim leLabelDom As String, _
wDocD As Word.Document, _
IsHd As InlineShape, _
leLabelSit As String, _
leLabelInt As String, _
leLabelGram As String, _
semaine As String
Set wDoc = ActiveDocument
If ActiveDocument.FormFields("ListeSemaine").DropDown.ListEntries.Item(ActiveDocument.FormFields("ListeSemaine").DropDown.Value).Name = "Semaine 1" Then
semaine = "S1"
lblMaterielS1.Caption = TextBoxMateriel.Text
lblEvaluationS1.Caption = TextBoxEvaluation.Text
End If
If ActiveDocument.FormFields("ListeSemaine").DropDown.ListEntries.Item(ActiveDocument.FormFields("ListeSemaine").DropDown.Value).Name = "Semaine 2" Then
semaine = "S2"
lblMaterielS2.Caption = TextBoxMateriel.Text
lblEvaluationS2.Caption = TextBoxEvaluation.Text
End If
If ActiveDocument.FormFields("ListeSemaine").DropDown.ListEntries.Item(ActiveDocument.FormFields("ListeSemaine").DropDown.Value).Name = "Semaine 3" Then
semaine = "S3"
lblMaterielS3.Caption = TextBoxMateriel.Text
lblEvaluationS3.Caption = TextBoxEvaluation.Text
End If
If ActiveDocument.FormFields("ListeSemaine").DropDown.ListEntries.Item(ActiveDocument.FormFields("ListeSemaine").DropDown.Value).Name = "Semaine 4" Then
semaine = "S4"
lblMaterielS4.Caption = TextBoxMateriel.Text
lblEvaluationS4.Caption = TextBoxEvaluation.Text
End If
If ActiveDocument.FormFields("ListeSemaine").DropDown.ListEntries.Item(ActiveDocument.FormFields("ListeSemaine").DropDown.Value).Name = "Semaine 5" Then
semaine = "S5"
lblMaterielS5.Caption = TextBoxMateriel.Text
lblEvaluationS5.Caption = TextBoxEvaluation.Text
End If
If ActiveDocument.FormFields("ListeSemaine").DropDown.ListEntries.Item(ActiveDocument.FormFields("ListeSemaine").DropDown.Value).Name = "Semaine 6" Then
semaine = "S6"
lblMaterielS6.Caption = TextBoxMateriel.Text
lblEvaluationS6.Caption = TextBoxEvaluation.Text
End If
If ActiveDocument.FormFields("ListeSemaine").DropDown.ListEntries.Item(ActiveDocument.FormFields("ListeSemaine").DropDown.Value).Name = "Semaine 7" Then
semaine = "S7"
lblMaterielS7.Caption = TextBoxMateriel.Text
lblEvaluationS7.Caption = TextBoxEvaluation.Text
End If
If ActiveDocument.FormFields("ListeSemaine").DropDown.ListEntries.Item(ActiveDocument.FormFields("ListeSemaine").DropDown.Value).Name = "Semaine 8" Then
semaine = "S8"
lblMaterielS8.Caption = TextBoxMateriel.Text
lblEvaluationS8.Caption = TextBoxEvaluation.Text
End If
If ActiveDocument.FormFields("ListeSemaine").DropDown.ListEntries.Item(ActiveDocument.FormFields("ListeSemaine").DropDown.Value).Name = "Semaine 9" Then
semaine = "S9"
lblMaterielS9.Caption = TextBoxMateriel.Text
lblEvaluationS9.Caption = TextBoxEvaluation.Text
End If
If ActiveDocument.FormFields("ListeSemaine").DropDown.ListEntries.Item(ActiveDocument.FormFields("ListeSemaine").DropDown.Value).Name = "Semaine 10" Then
semaine = "S10"
lblMaterielS10.Caption = TextBoxMateriel.Text
lblEvaluationS10.Caption = TextBoxEvaluation.Text
End If
If ActiveDocument.FormFields("ListeSemaine").DropDown.ListEntries.Item(ActiveDocument.FormFields("ListeSemaine").DropDown.Value).Name = "Semaine 11" Then
semaine = "S11"
lblMaterielS11.Caption = TextBoxMateriel.Text
lblEvaluationS11.Caption = TextBoxEvaluation.Text
End If
For k = 1 To 11
leLabelDom = "lblDomaine" & k & semaine
leLabelSit = "lblSituation" & k & semaine
leLabelInt = "lblIntention" & k & semaine
leLabelGram = "lblGrammaire" & k & semaine
If wDoc.FormFields("ListeDomaine" & k).DropDown.ListEntries.Count <> 0 And _
wDoc.FormFields("ListeDomaine" & k).DropDown.ListEntries.Item(wDoc.FormFields("ListeDomaine" & k).DropDown.Value).Name <> "Choisissez un domaine." _
Then
If wDoc.InlineShapes.Count <> 0 Then
For Each IsH In wDoc.InlineShapes
If IsH.Type = wdInlineShapeOLEControlObject Then
If TypeName(IsH.OLEFormat.Object) = "Label" Then
If IsH.OLEFormat.Object.Name = leLabelDom Then
IsH.OLEFormat.Object.Caption = wDoc.FormFields("ListeDomaine" & k).DropDown.ListEntries.Item(wDoc.FormFields("ListeDomaine" & k).DropDown.Value).Name
End If
End If
End If
Next
End If
End If
If wDoc.FormFields("ListeSituation" & k).DropDown.ListEntries.Count <> 0 _
Then
If wDoc.FormFields("ListeSituation" & k).DropDown.Value <> 0 _
Then
If wDoc.FormFields("ListeSituation" & k).DropDown.ListEntries.Item(wDoc.FormFields("ListeSituation" & k).DropDown.Value).Name <> "Choisissez une situation" _
Then
If wDoc.InlineShapes.Count <> 0 Then
For Each IsH In wDoc.InlineShapes
If IsH.Type = wdInlineShapeOLEControlObject Then
If TypeName(IsH.OLEFormat.Object) = "Label" Then
If IsH.OLEFormat.Object.Name = leLabelSit Then
IsH.OLEFormat.Object.Caption = wDoc.FormFields("ListeSituation" & k).DropDown.ListEntries.Item(wDoc.FormFields("ListeSituation" & k).DropDown.Value).Name
End If
End If
End If
Next
End If
End If
End If
End If
If wDoc.FormFields("ListeIntention" & k).DropDown.ListEntries.Count <> 0 And _
wDoc.FormFields("ListeIntention" & k).DropDown.Value <> 0 _
Then
If wDoc.InlineShapes.Count <> 0 Then
For Each IsH In wDoc.InlineShapes
If IsH.Type = wdInlineShapeOLEControlObject Then
If TypeName(IsH.OLEFormat.Object) = "Label" Then
If IsH.OLEFormat.Object.Name = leLabelInt Then
IsH.OLEFormat.Object.Caption = wDoc.FormFields("ListeIntention" & k).DropDown.ListEntries.Item(wDoc.FormFields("ListeIntention" & k).DropDown.Value).Name
End If
End If
End If
Next
End If
End If
If wDoc.FormFields("ListeGrammaire" & k).DropDown.ListEntries.Count <> 0 And _
wDoc.FormFields("ListeGrammaire" & k).DropDown.ListEntries.Item(wDoc.FormFields("ListeGrammaire" & k).DropDown.Value).Name <> "Choisissez un niveau." _
Then
If wDoc.InlineShapes.Count <> 0 Then
For Each IsH In wDoc.InlineShapes
If IsH.Type = wdInlineShapeOLEControlObject Then
If TypeName(IsH.OLEFormat.Object) = "Label" Then
If IsH.OLEFormat.Object.Name = leLabelGram Then
IsH.OLEFormat.Object.Caption = wDoc.FormFields("ListeGrammaire" & k).DropDown.ListEntries.Item(wDoc.FormFields("ListeGrammaire" & k).DropDown.Value).Name
End If
End If
End If
Next
End If
End If
Next k
Set wDoc = Nothing
End Sub
In your edit, you try to use a property for a String, but Properties are only for Object variables.
So, you need to find where are stored the controls, in InlineShapes and then loop and filter it to narrow it down to your specific control and change its value.
Here is something that should work or at least is probably close (can't test it) :
Sub OuO()
Dim leLabelDom As String, _
wDoc As Word.Document, _
wListE As DropDown, _
IsH As InlineShape
Set wDoc = wDoc
For k = 1 To 11
leLabelDom = "lblDom" & k & "W1"
Set wListE = wDoc.FormFields("ListeDomaine" & k).DropDown
If wListE.ListEntries.Count <> 0 And _
wListE.ListEntries.Item(wListE.Value).Name <> "Choisissez un domaine." _
Then
If wDoc.InlineShapes.Count <> 0 Then
For Each IsH In wDoc.InlineShapes
If IsH.Type <> wdInlineShapeOLEControlObject Then
Else
'filter on name
With IsH.OLEFormat.Object
If .Name <> leLabelDom Then
Else
.Caption = wListE.ListEntries.Item(wListE.Value).Name
End If
End With
End If
Next IsH
Else
End If
Else
End If
Next k
Set wDoc = Nothing
Set wListE = Nothing
End Sub