Compare DateDiff issue - vbscript

I need to compare 2 dates to find out if a computer is EOL or very EOL. Different kind of text is depending on if it is a EOL or VEOL.
Current date is 29-08-2016
Ex. 1 lstrValue = 31-12-2016 = 4
Ex. 2 lstrValue = 31-07-2016 = -1
select case DateDiff("m",Date,CDATE(lstrValue))
case 1, 2, 3
bEOL = true
case else
bVeryEOL = true
end select
The problem in my exampel is that if DateDiff is either 4, 5, 6, ect the bVeryEOL is true. That is not what I'm looking for. I'm only looking for bVeryEOL is true, if the datediff is negativ

I believe you are looking for something like this, then:
EDIT: Changed the code because previous was not valid VBScript
Dim strResult : strResult = DateDiff("m",Date,CDATE(lstrValue))
Select case strResult
Case 1, 2, 3
bEOL = true
Case Else
If strResult < 0 Then
bVeryEOL = True
Else
'add logic
End If
End select

Related

How to check if two or more conditions are met vs only one of them is true?

I'm using the following script with a software which reads a CheckBox using OMR and outputs the data to an XML file.
Is there a way I can change it to say if more than one box has been checked, the data output should be the first checked box in the list?
Hope this makes sense.
Any help would be appreciated.
Dim installer
q_a1= Metadata.Values("OMR_FRED_P2")
q_a2= Metadata.Values("OMR_JON_P2")
q_a3= Metadata.Values("OMR_MATT_P2")
q_a4= Metadata.Values("OMR_STEVE_P2")
If q_a1 = "Filled" Then
installer = "Fred"
End If
If q_a2 = "Filled" then
installer = "Jon"
End If
If q_a3 = "Filled" then
installer = "Matt"
End If
If q_a4 = "Filled" then
installer = "Steve"
End If
call Metadata.SetValues("CompleteBy",installer)
You could do something like this:
Dim a1Checked, a2Checked, a3Checked, a4Checked
Dim numberOfChecked
a1Checked = (q_a1 = "Filled")
a2Checked = (q_a2 = "Filled")
a3Checked = (q_a3 = "Filled")
a4Checked = (q_a4 = "Filled")
numberOfChecked = Abs(a1Checked + a2Checked + a3Checked + a4Checked)
If a1Checked Or numberOfChecked > 1 Then
installer = "Fred"
ElseIf a2Checked Then
installer = "Jon"
ElseIf a3Checked Then
installer = "Matt"
ElseIf a4Checked Then
installer = "Steve"
Else
' Decide what you want to do if none is checked.
End If
Call Metadata.SetValues("CompleteBy", installer)
In VBScript, the numeric value of a "boolean true" value is -1 and of the false value is 0.
The above code simply adds the values together. If two conditions are met, the total would be -2, then we use the Abs function to get the abstract value (i.e., returning 2 instead of -2). After that, you can easily check if two or more conditions are met by using numberofChecked > 1.

VBA code causing excel lagging

My code below is used to decrements date based on the first date entered, and if column B is filled. As the data imported to Excel is very large, so this calculation is now causing my excel to lag. Is there a way to speed it up??
For i = 1 To rowNow - 3
newDate = DateAdd("d", -i, oldDate)
For Each Cell In Range("A:A").Cells
If IsEmpty(Cell) = True And IsEmpty(Range("B:B")) = False Then Cell.Value = newDate: Exit For
Next
Next
Maybe this,depending on what's in column B:
For i = 1 To rowNow - 3
newDate = DateAdd("d", -i, oldDate)
With Range("A:A")
On Error Resume Next
Intersect(.SpecialCells(xlCellTypeBlanks), .Offset(, 1).SpecialCells(xlCellTypeConstants).Offset(, -1))(1).Value = newDate
End With
Next i

slow loop when automating Excel

I need to create an excel sheet which contains a visual representation of a bit array. Presently I test the bit value and update the cell contents
For h = 1 To 128
value = Mid(array, h,1)
If value = "1" Then
xl.Application.Sheets("Sheet1").Cells(129 - h,5).value = "X"
Else
xl.Application.Sheets("Sheet1").Cells(129 - h,5).value = ""
End If
Next
If I add a WScript.Sleep 100 before Next then the output result in the excel sheet is correct.
If not, then the X's are in the wrong places.
Initially I thought that it was Excel that was slow, so I tried making a CSV file that I could simply import later, but with the same results: too fast and the X's are in the wrong positions, slow it down and they are correct.
There are around 128 of these 128bit arrays, and if each takes 3 ~ 5 seconds then making this sheet will take forever.
Does anyone know how I can achieve this quickly? I am open to other ideas/solutions (with VBS) outputting the excel file.
Thanks!
Try putting the array into the range in one go, like this
ReDim dat(1 To 128, 1 To 1)
For h = 1 To 128
v = Mid$(arr, h, 1)
dat(129 - h, 1) = IIf(v = "1", "X", "")
Next
xl.Application.Sheets("Sheet1").Cells(1, 5).Resize(128, 1).Value = dat
This worked for me (tested in vbscript rather than vba).
As it uses an array, the "" output as part of an IF is redundant as the array is blank, so it is only necessary to write the X when the bit is 1.
Dim StrArr
Dim xl
Set xl = CreateObject("excel.application")
Set wb = xl.Workbooks.Add
'sample array
StrArr = "1100111011001110110011101100111011001110110011101100111011001110110011101100111011001110110011101100111011001110110011101100111"
Dim X(128, 1 )
For lngrow = 1 To UBound(X)
If Mid(StrArr, lngrow, 1) = "1" Then X(lngrow, 0) = 1
Next
wb.Sheets(1).Cells(1, 5).Resize(UBound(X), 1).Value = X
xl.Visible = True

Excel Macro, vlookup function works slow, ways to speed up macro

Hello stackexchange community.
I've built a simple tables converter, the main function of which is to convert the table from
1a Value
1b Value
1c Value
1d Value
to
a b c d
1 Value Value Value Value
Unfortunately, the macro runs pretty slow (~ 3 lines per second for one column).
I'd really appreciate if someone could take a look at my piece of code and suggest the way to speed it up.
Here's the piece of code:
Dim LastFinalList As Integer: LastFinalList = Sheet1.Range("O1000").End(xlUp).Row
For Col = 16 To 19
For c = 2 To LastFinalList
searchrange = Sheet1.Range("J:L")
lookfor = Sheet1.Cells(c, 15) & Sheet1.Cells(1, Col)
CountFor = Application.VLookup(lookfor, searchrange, 3, False)
If IsError(CountFor) Then
Sheet1.Cells(c, Col).Value = "0"
Else
Sheet1.Cells(c, Col).Value = CountFor
End If
Next c
Next Col
Thanks in advance and best regards!
UPD:
The Data in unconverted table looks like this (e.g):
Updated by Macro
Value Number Type Key Count Average Value
10 1 a 1a 2 20
30 1 a 1a 2 20
40 1 b 1b 1 40
50 1 c 1c 1 50
So it is also required to calculate averages of repeating types, create a unique list of Numbers (which is LastFinalList in my case) and finally convert it to this:
Number a b c
1 20 40 50
application.vlookupseraches by Number&Type Key, which is also assigned in the unconverted table by macro. The same time those Keys are counted, in order to calculate average for the repeating ones.
Everything works in a blink of an eye till it comes to 'to update final table part.
Full Code:
Sub ConvertToTable()
Dim LastMeter As Integer: LastMeter = Sheet1.Range("I1000").End(xlUp).Row
Sheet1.Range(Cells(2, 9), Cells(LastMeter, 9)).AdvancedFilter Action:=xlFilterCopy, CopyToRange:=Sheet1.Range("O2"), Unique:=True
Sheet1.Range("O1").Value = "The List"
Sheet1.Range("O2").Delete Shift:=xlUp
' to assign keys
For i = 2 To LastMeter
Set CountOpt = Sheet1.Cells(i, 10)
Sheet1.Cells(i, 10).FormulaR1C1 = "=r[0]c[-1]&r[0]c[-2]"
Sheet1.Cells(i, 11).FormulaR1C1 = "=COUNTIF(c10:c10, r[0]c10)"
Next i
'to calculate averages
For x = 2 To LastMeter
If Sheet1.Cells(x, 11).Value = 1 Then
Sheet1.Cells(x, 12).FormulaR1C1 = "=rc7"
ElseIf Sheet1.Cells(x, 11).Value > 1 Then
If Sheet1.Cells(x, 10).Value <> Sheet1.Cells(x - 1, 10).Value Then
Sheet1.Cells(x, 12).FormulaR1C1 = "=ROUND((SUM(rc7:r[" & Sheet1.Cells(x, 11).Value - 1 & "]c7)/" & Sheet1.Cells(x, 11).Value & "),4)"
Else
Sheet1.Cells(x, 12).FormulaR1C1 = "=r[-1]c12"
End If
End If
Next x
'to update final table
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Dim LastFinalList As Integer: LastFinalList = Sheet1.Cells(Rows.Count, 15).End(xlUp).Row
For Col = 16 To 19
For c = 2 To LastFinalList
searchrange = Sheet1.Range("J:L")
lookfor = Sheet1.Cells(c, 15) & Sheet1.Cells(1, Col)
CountFor = Application.VLookup(lookfor, searchrange, 3, False)
If IsError(CountFor) Then
Sheet1.Cells(c, Col).Value = "0"
Else
Sheet1.Cells(c, Col).Value = CountFor
End If
Next c
Next Col
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Sheet1.Range("O1").Select
End Sub
Also, initially i had a SUMIF formula instead of application.vlookup to be input in each cell in the converted table. But the code was working as slow as now an was bit bulky, that's why i've decide to switch to VLOOKUP.
The thing is, if it actually the way application.vlookup works (with 0.3sec delay for each row), then i guess there's nothing that can be done, and i'm ok to accept that. Although, if that's not the case, i'd really appreciate if someone could help me out and speed up the process.
Thanks!
You can redefine your LastFinalList variable something like
LastFinalList = Sheets("Sheet1").UsedRange.Rows.Count
OR
LastFinalList = Sheets("Sheet1").Cells(Rows.Count, 2).End(xlUp).Row
instead of explicitly defining used range.
Also use following line of code before your code
Application.ScreenUpdating = False
(Turn screen updating off to speed up macro code. User won't be able to see what the macro is doing, but it will run faster.)
After the whole code runs you can(optional) turn screen updating on with
Application.ScreenUpdating = True
It appears that application.vlookup in my particular case was indeed working very slow (no idea why, though). I've managed to improve macro by replacing vlookup with SUMIF formula in each cell, so now the converted table is updated instantly. Thanks everyone who participated and provided their suggestions!

VBScript MS-Word Find & Replace Char for Addin Fields

Okay, I've searched and searched and am hoping someone here can help me out.
I've been trying to get a VBScript program to open a word document, search for a specific char and replace it with a Addin field (i.e. { SEQ # } )
Here's what I have thus far:
1 Const wdReplaceAll = 2
2 Set objWord = CreateObject("Word.Application")
3 objWord.Visible = True
4
5 Set ObjDoc = objWord.Documents.Open("C:\path\to\.doc")
6 Set objSelection = objWord.Selection
7
8 objSelection.Find.Text = "#"
9 objSelection.Find.Forward = True
10 objSelection.MatchWholeWord = True
11
12 objSelection.Find.Replace.Text = "replacement text"
13
14 objSelection.Find.Execute ,,,,,,,,,,wdReplaceAll
This code works for "Find/Replace" but does not work for fields.
Much help would be awesome! Thanks!
Replace replaces text, but you want to add a field. That's an entirely different thing. I'd suggest to Find the search text (leaves the text selected) and then Add the field (replaces the selected text):
With objWord.Selection
.Find.Text = "#"
.Find.Forward = True
.Find.MatchWholeWord = True
.Find.Execute
.Fields.Add .Range, -1, "SEQ #", True
End With
To replace all occurrences of the search string you have to create a loop that keeps executing .Find.Execute until no further occurrences are found. The return value of the Execute method indicates if another match was found.
With objWord.Selection
.Find.Text = "#"
.Find.Forward = True
.Find.MatchWholeWord = True
Do
found = .Find.Execute
If found Then .Fields.Add .Range, -1, "SEQ #", True
Loop While found
End With
Make sure your cursor is positioned at the beginning of the document before you run the above code, otherwise you might miss occurrences of your search text.

Resources