objReminder.Start = Range("h" & i) not working - vba

I have this code:
Sub StoreReminders()
Dim LastRow As Long
Dim i As Integer
LastRow = ActiveSheet.UsedRange.Rows.Count
i = 2
Debug.Print LastRow
Dim appOL As Object
Dim objReminder As Object
Set appOL = GetObject(, "Outlook.application")
Set objReminder = appOL.CreateItem(1) ' olAppointmentItem
For i = 2 To LastRow
Debug.Print i
Debug.Print Range("h" & i)
objReminder.Start = Range("h" & i)
objReminder.Duration = Range("I" & i)
objReminder.Subject = "Renew " & Range("a" & i)
objReminder.ReminderSet = True
objReminder.Save
Next i
End Sub
It breaks at objReminder.Start = Range("h" & i) because according to the Debug.Print code, it is returning the entire column of dates instead of just the date in H2
Does the Range("a" & i) code not work in conjunction with objReminder.Start?
Debug.print prints it out correctly.

If you check the MSDN entry for the Start property then it says:
Returns or sets a Date indicating the starting date and time for the appointment or Journal entry. Read/write.
(their emphasis)
So, in your VBA code, I would change this line:
objReminder.Start = Range("h" & i)
To this:
objReminder.Start = CDate(Range("h" & i).Value)
Using the CDate function which converts a value to a date.

Related

"Object required" error though i've set all variables in Excel VBA

I've set all variables but I still keep getting the error "object required" at
For Each cll In OHLC
This is my code:
Sub hellohello()
Dim i As Integer
Dim OHLC, cll As Range
Dim stoplossb, entrypriceb As Variant
stoplossb = 1
entrypriceb = 1
i = 1
For i = 63 To 166
If Range("M" & i).Value = "buy" Then
stoplossb = Range("X" & i)
entrypriceb = Range("w" & i)
Set OHLC = Range("B" & i & ":" & "E10000")
' Set twndlow = Range("K" & i & ":" & "K10000")
End If
For Each cll In OHLC
If cll.Value < stoplossb Then
Range("Y" & cll.Row) = cll.Value
Exit For
End If
Next cll
Next i
End Sub
What's my error?
Set OHLC to an empty Range in an else statement before end if.
Or put the for inside the if block
Sub hellohello()
Dim i As Integer
Dim OHLC, cll As Range
Dim stoplossb, entrypriceb As Variant
stoplossb = 1
entrypriceb = 1
i = 1
For i = 63 To 166
If Range("M" & i).Value = "buy" Then
stoplossb = Range("X" & i)
entrypriceb = Range("w" & i)
Set OHLC = Range("B" & i & ":" & "E10000")
' Set twndlow = Range("K" & i & ":" & "K10000")
For Each cll In OHLC
If cll.Value < stoplossb Then
Range("Y" & cll.Row) = cll.Value
Exit For
End If
Next cll
End If
Next i
End Sub
The reason you are getting an error is because your IF statement is not true, therefore you never get to the line that sets OHLC as a range. Since the range is never set the range is equal to nothing.
what Carlos is saying is that you have an outer loop that runs from 63 to 166, inside that loop you have an IF statement whereby you decide whether or not to set OHLC but then you have an inner loop which runs regardless of whether or not OHLC was set in the IF statement.. I think you need to move the End If down to just after next cll that way your inner FOR loop will only run when OHLC is set
Dim OHLC As Range, cll As Range

Need a real VBA equivalent for Excel Value function

As mentioned in the title, I need a VBA equivalent to the Excel Value function. My data set looks like this: Data set example
What I am looking for is VBA code equivalent to this: =Value(A2)+Value(B2). That would go in column C
The output must be the same as that function. For the given example, column C should end up looking like this: End product
More than that, it needs to only have the value in the cell after the macro is run, rather than displaying the value and still having that formula in it.
Here is what I have done so far:
For i = 1 To LastRow
strValue = Val(sht.Range("A" & i))
strValue1 = Val(sht.Range("B" & i))
sht.Range("C" & i).Value = strValue + strValue1
Next i
I also tried variations on this, a couple of which are shown below:
For i = 1 To LastRow
strValue = Evaluate(sht.Range("A" & i))
strValue1 = Evaluate(sht.Range("B" & i))
sht.Range("C" & i).Value = strValue + strValue1
Next i
For i = 1 To LastRow
strValue = sht.Range("A" & i)
strValue1 = sht.Range("B" & i)
strVal = Evaluate(strValue)
strVal1 = Evaluate(strValue1)
sht.Range("C" & i).Value = strVal + strVal1
Next i
I can't find anything that will work for me. The output in C for the example set ends up being just 9. Pretty sure it is taking the first number in A and adding it to the first number in B. So when the hour in B changes to 1 C displays 10.
I also tried simply:
For i=1 To LastRow
sht.Range("C" & i).Value = sht.Range("A" & i).Value + sht.Range("B" & i).Value
Next i
That just concatenated the text to the format 9/03/15 00:00:00
Any and all help appreciated. Bonus if you can point me in the right direction for changing the final C values from that number (ie. 42250.00017) to the custom date/time format 'yyyy-mm-dd hh:mm:ss'.
Edit: Here is my code up to the sticking point. Everything else works as I want it to, the only problem is with the last For loop.
Sub sbOrganizeData()
Dim i As Long
Dim k As Long
Dim sht As Worksheet
Dim LastRow As Long
Dim sFound As String
Dim rng As Range
Dim sheet As Worksheet
Dim Sheet2 As Worksheet
Dim strFile As String
Dim strCSV As String
Dim strValue As Double
Dim strValue1 As Double
Dim strVal As Long
Dim strVal1 As Long
Application.DisplayAlerts = False
Sheets("all016").Delete
Sheets("Sheet1").Delete
Application.DisplayAlerts = True
Set sheet = Sheets.Add
Set Sheet2 = Sheets.Add
sheet.Name = "all016"
Sheet2.Name = "Sheet1"
strFile = ActiveWorkbook.Path
strCSV = "*.csv"
sFound = Dir(strFile & "\*.csv")
If sFound <> "" Then
Workbooks.Open Filename:=strFile & "\" & sFound
End If
Range("A1").CurrentRegion.Copy Destination:=Workbooks("solar.xlsm").Sheets("all016").Range("A1")
Workbooks(sFound).Close
Set sht = ThisWorkbook.Sheets("all016")
LastRow = sht.Cells.Find("*", searchorder:=xlByRows, searchdirection:=xlPrevious).Row
sht.Range("C1").EntireColumn.Insert
For i = 1 To LastRow
'Code that doesn't quite work here'
sht.Range("C" & i).NumberFormat = "yyyy-mm-dd hh:mm:ss"
Next i
The issue is that the dates and times are strings so something like this will work:
For i = 2 To LastRow
strValue = Evaluate("VALUE(TRIM(" & sht.Range("A" & i).Address(1,1,,1) & "))")
strValue1 = Evaluate("VALUE(TRIM(" & sht.Range("B" & i).Address(1,1,,1) & "))")
sht.Range("C" & i).Value = strValue + strValue1
'the format
sht.Range("C" & i).NumberFormat = "mm/dd/yy hh:mm:ss"
Next i
You have to reference the .Value2 field of the range element as:
For i = 1 To LastRow
sht.Range("C" & i).Value2 = sht.Range("A" & i).Value2 + sht.Range("B" & i).Value2
Next i
The value is free of formatting and just in Excel's time/date code as you want your final result to be. Cheers,

Application defined or object defined error - depending on which Worksheet is opened

I'm having an issue that I am struggling to solve as it's a bit specific. I have code that does copy and paste from one sheet to others. Each part of the code basically copies part from the master sheet "current" to the specified sheet.
When I run my code I receive an error "Application defined or object defined error" and the code stops at the work sheet "Dividend yield" after the following line
Worksheets("div. yield").Range("B7").Select
However if I open the sheet "Dividend yield" and run my code from there it will work fine until the last sheet "Reverse PE" where it will again throw and error "Application defined or object defined error" after the line
Worksheets("Reverse_PE").Range("B9").Select
I guess the error is related to the next coming rows with Autofill method but I have not found any useful solutions to this problem. Could somebody please advise me how to solve this error?
Full macros code is below.
Function getYield() As Double
Dim appIE As Object
Set appIE = CreateObject("internetexplorer.application")
With appIE
.Navigate "http://uk.investing.com/rates-bonds/world-government-bonds"
.Visible = False
End With
Do While appIE.Busy
DoEvents
Loop
Set allRowOfData = appIE.document.getElementById("pair_23705")
Dim myValue As Double: myValue = allRowOfData.Cells(2).innerHTML
appIE.Quit
Set appIE = Nothing
Worksheets("Reverse_PE").Range("B7").Value = myValue
Worksheets("Reverse_PE").Range("B7").Value = Worksheets("Reverse_PE").Range("B7").Value / 100
End Function
Sub adjust()
Dim copyAdress As Range
Dim copyRange As Range
Dim lastRow As Long
Dim Median As Range
'''PE'''
Set copyAdress = Worksheets("current").Range("A1:CJ10000").Find("PE_RATIO", lookat:=xlPart)
lastRow = Cells(65536, copyAdress.Column).End(xlUp).Row
Set copyRange = Worksheets("current").Range(Cells(copyAdress.Row + 1, copyAdress.Column), Cells(lastRow, copyAdress.Column))
Worksheets("PE").Range("B1").EntireColumn.Insert
copyRange.Copy Destination:=Sheets("PE").Range("B7", "B" & lastRow)
Worksheets("PE").Range("B2").Value = Worksheets("current").Range("A1").Value
Worksheets("PE").Range("B3").FormulaArray = "=MEDIAN(B7:B" & lastRow + 2 & ")"
Worksheets("PE").Range("B5").Font.Bold = True
Worksheets("PE").Range("B5").FormulaArray = "=IF(ISNUMBER(VLOOKUP($A$5,$A$7:$HI$1750,COLUMN(B4),FALSE)),VLOOKUP($A$5,$A$7:$HI$1750,COLUMN(B4),FALSE)," & Chr(34) & NA & Chr(34) & ")"
Set copyRange = Worksheets("current").Range("A5", "A" & lastRow)
copyRange.Copy Destination:=Sheets("PE").Range("A7", "A" & lastRow + 2)
''Dividend yield'''
Set copyRange = Worksheets("current").Range("A5", "A" & lastRow)
copyRange.Copy Destination:=Sheets("div. yield").Range("A7", "A" & lastRow + 2)
Worksheets("div. yield").Range("B7").FormulaArray = "=IF(ISNUMBER(current!X5),current!X5," & Chr(34) & Chr(34) & ")"
Worksheets("div. yield").Range("B7").Select
Selection.AutoFill Destination:=Sheets("div. yield").Range("B7:B" & lastRow + 2), Type:=xlFillDefault
'''PE Forward'''
Set copyAdress = Worksheets("current").Range("A1:CJ10000").Find("P/E-Ratio 03E", lookat:=xlPart)
lastRow = Cells(65536, copyAdress.Column).End(xlUp).Row
Set copyRange = Worksheets("current").Range(Cells(copyAdress.Row + 3, copyAdress.Column), Cells(lastRow, copyAdress.Column))
Worksheets("PE_forward").Range("B1").EntireColumn.Insert
copyRange.Copy Destination:=Sheets("PE_forward").Range("B7", "B" & lastRow + 2)
Worksheets("PE_forward").Range("B2").Value = Worksheets("current").Range("A1").Value
Worksheets("PE_forward").Range("B3").FormulaArray = "=MEDIAN(B7:B" & lastRow + 2 & ")"
Worksheets("PE_forward").Range("B5").Font.Bold = True
Worksheets("PE_forward").Range("B5").FormulaArray = "=IF(ISNUMBER(VLOOKUP($A$5,$A$7:$HI$1750,COLUMN(B751),FALSE)),VLOOKUP($A$5,$A$7:$HI$1750,COLUMN(B751),FALSE)," & Chr(34) & NA & Chr(34) & ")"
Worksheets("PE_forward").Columns("B").Replace What:="#VALUE!", Replacement:=""
Worksheets("PE_forward").Range("B3").NumberFormat = ""
Set copyRange = Worksheets("current").Range("A5", "A" & lastRow)
copyRange.Copy Destination:=Sheets("PE_forward").Range("A7", "A" & lastRow + 2)
'''Reverse PE'''
Set copyRange = Worksheets("current").Range("A5", "A" & lastRow)
copyRange.Copy Destination:=Sheets("Reverse_PE").Range("A9", "A" & lastRow + 4)
Worksheets("Reverse_PE").Range("B1").EntireColumn.Insert
Worksheets("Reverse_PE").Range("B2").Value = Worksheets("current").Range("A1").Value
Worksheets("Reverse_PE").Range("B5").FormulaArray = "=IF(ISNUMBER(VLOOKUP($A$5,$A$9:$HI$1750,COLUMN(B751),FALSE)),VLOOKUP($A$5,$A$9:$HI$1750,COLUMN(B751),FALSE)," & Chr(34) & NA & Chr(34) & ")"
getYield
Worksheets("Reverse_PE").Range("B3").FormulaArray = "=MEDIAN(B9:B" & lastRow + 4 & ")"
Worksheets("Reverse_PE").Range("B9").FormulaArray = "=IF(ISNUMBER(PE!B7),1/PE!B7," & Chr(34) & Chr(34) & ")"
Worksheets("Reverse_PE").Range("B9").Select
Selection.AutoFill Destination:=Sheets("Reverse_PE").Range("B9:B" & lastRow + 4), Type:=xlFillDefault
Worksheets("Reverse_PE").Range("B3:B" & lastRow + 4).Select
Selection.Style = "Percent"
Selection.NumberFormat = "0.00%"
You can't use the select method unless the sheet is first active, so add this line:
Worksheets("div. yield").Activate
Worksheets("div. yield").Range("B7").FormulaArray = "=IF(ISNUMBER(current!X5),current!X5," & Chr(34) & Chr(34) & ")"
and later at:
Worksheets("Reverse_PE").Activate
Worksheets("Reverse_PE").Range("B9").Select
There are much faster and more maintainable ways of doing what you're trying to do, but the above sheet activation will solve your immediate problem.
Don't forget to activate each sheet before you try to select one of the cells on it.

Do while loop code wont play

I am trying to loop through a list of data then and copy the rows that contain "WIP" into a second tab. yet the code will nor do anything when I hit execute. Can someone explain why?
Thank you.
Sub Update_LvL1_WIP()
Dim BrowFi As Integer
Dim BrowWIP1 As Integer
Dim dblSKU As Double
Dim strDescription As String
Dim strType As String
BrowFi = (ActiveSheet.Range("A" & Rows.Count).End(xlUp).Row) + 1
Do While BrowFi > 4
If Range("G" & BrowFi).Value = "WIP" Then
strType = Range("G" & BrowFi).Value
strDescription = Range("F" & BrowFi).Value
dblSKU = Range("E" & BrowFi).Value
Worksheets("WIP 1").Activate
BrowWIP1 = (ActiveSheet.Range("A" & Rows.Count).End(xlUp).Row) +1
Range("A" & BrowWIP1).Value = dblSKU
Range("B" & BrowWIP1).Value = strDescription
Range("B" & BrowWIP1).Value = strType
Else
BrowFi = BrowiF - 1
End If
Loop
End Sub
You have a typo in your decrement variable
BrowFi = BrowiF - 1
should be
BrowFi = BrowFi - 1
Since BrowiF was not defined it was treated as 0 and so you were setting BrowFi to -1 on the first run through the loop.
It may be worth using Option Explicit to help catch these errors.

How to increase only last digit of a serial number string in Excel VBA?

I'm new to vba and trying to write a barcode scanner algorithm. It works fine right now but I want to keep serial numbers in my exel table and their structure has to be like "A151000". I want with each barcode entered a cell with an inputbox also be assigned to a serial number. for example when a new entry(Barcode) written in column C I want in column B serial numbers last digit increased by 1 and stored in that cell automatically.
Right now I can drag the cell from corner and exel increases the last digit. How can I trigger this with new entries automatically? Thanks in advance.
A151000
A151001
A151002
...
Sub DataInput()
Dim SearchTarget As String
Dim myRow As Long
Dim Rng As Range
Static PrevCell As Range
Dim FoundCell As Range
Dim CurCell As Range
Dim a As String
Dim Target As Range
Dim buttonclick As Boolean
V = True
If PrevCell Is Nothing Then
myRow = Selection.Row
Set PrevCell = Range("C" & myRow)
End If
Set Rng = Range("C:C,C:C") 'Columns for search defined here
With Rng
Set FoundCell = .Cells.Find(What:=SearchTarget, _
After:=PrevCell, LookIn:=xlFormulas, LookAt:= _
xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlNext, _
MatchCase:=True)
End With
Dim Eingabezahl As String
Do While Eingabezahl! = ""
Eingabezahl = InputBox("Last barcode scanned" & " " & Eingabezahl)
Range("C" & Range("C" & Rows.Count).End(xlUp).Row + 1) = Eingabezahl
Range("D" & Range("D" & Rows.Count).End(xlUp).Row + 1) = Now()
Range("E" & Range("E" & Rows.Count).End(xlUp).Row + 1) = "VALID"
Loop
End Sub
TO use the Autofill function and not change your original code you could just add in the autofill in your sub:
Dim Eingabezahl As String
Dim rngLastBCell As Range
Do While Eingabezahl = ""
Eingabezahl = InputBox("Last barcode scanned" & " " & Eingabezahl)
Set rngLastBCell = Range("B" & Rows.Count).End(xlUp)
rngLastBCell.AutoFill Destination:=Range(rngLastBCell, rngLastBCell.Offset(1)), Type:=xlFillDefault
Range("C" & Range("C" & Rows.Count).End(xlUp).Row + 1) = Eingabezahl
Range("D" & Range("D" & Rows.Count).End(xlUp).Row + 1) = Now()
Range("E" & Range("E" & Rows.Count).End(xlUp).Row + 1) = "VALID"
Loop
Or you could use the following that using the same concept (an autofill) but condenses al of your calls to the worksheet into a single line:
Dim Eingabezahl As String
Dim rngLastBCell As Range
Do While Eingabezahl = ""
Eingabezahl = InputBox("Last barcode scanned" & " " & Eingabezahl)
Set rngLastBCell = Range("B" & Rows.Count).End(xlUp)
rngLastBCell.AutoFill Destination:=Range(rngLastBCell, rngLastBCell.Offset(1)), Type:=xlFillDefault
rngLastBCell.Offset(1, 1).Resize(, 3) = Array(Eingabezahl, Now(), "VALID")
Loop
Although I would recommend just using appenending the current row to the end of your serial and not making as many calls to the worksheet by using an array:
Dim rngB As Range
Dim Eingabezahl As String
Dim SerialBase As String
SerialBase = "A15100"
Do While Eingabezahl = ""
Eingabezahl = InputBox("Last barcode scanned" & " " & Eingabezahl)
Set rngB = Range("B" & Rows.Count).End(xlUp).Offset(1)
rngB.Resize(, 4).Value = Array(SerialBase & rngB.Row, Eingabezahl, Now(), "VALID")
Loop