Excel not recognizing year when changing to date format with VBA - vba

I'm having trouble changing to date format. I have cells containing different dates but not all of them are formatted as date. One of them is "yy-mm-dd", for example "13-04-08", but it is formatted as General.
I'm using this code:
xCell = Format(xCell, "yyyy-mm-dd")
Problem is that excel cannot tell if "13" or "08" is the "yyyy" so it doesn't change anything. How do I solve this? Do I need to tell excel which numbers are year before it changes the date, and how do I do that? Can it be included in the Format method?
EDIT:
I think I need to explain the whole thing as the problem seems to lay somewhere else.
The cells containing the dates look like this from start, being formatted as General:
13-05-06 A
13-05-21 A
...
I remove the unwanted 'A' with this code:
Sub rensa()
Dim Found As Range
For Each xCell In Range("D2:D999")
If IsEmpty(xCell.Value) Then Exit For
Set Found = xCell.Find(What:="A", LookIn:=xlValues, LookAt:=xlPart)
If Found Is Nothing Then
Else
xCell.Value = Left(xCell.Value, Len(xCell.Value) - 1)
End If
Next xCell
End Sub
I have tried these codes to set the cell format to date:
Range("D2:D999").NumberFormat = "yyyy-mm-dd"
Range("D2:D999").NumberFormat = "m/d/yyyy"
I have also tried to implement them in the For loop like this:
Sub rensa()
Dim Found As Range
For Each xCell In Range("D2:D999")
If IsEmpty(xCell.Value) Then Exit For
Set Found = xCell.Find(What:="A", LookIn:=xlValues, LookAt:=xlPart)
If Found Is Nothing Then
xCell.NumberFormat = "yyyy-mm-dd"
Else
xCell.Value = Left(xCell.Value, Len(xCell.Value) - 1)
xCell.NumberFormat = "yyyy-mm-dd"
End If
Next xCell
End Sub
But that didn't work as I wanted either. Everything makes the result look like this, still formatted as General:
13-05-06
13-05-21
...
So the A is gone, but nothing else changes.

i just added something in your code. See below lines with comments
Sub rensa()
Dim Found As Range
Dim xcell As Range
Dim date_val As Date
For Each xcell In Range("D1:D999")
If IsEmpty(xcell.Value) Then Exit For
Set Found = xcell.Find(What:="A", LookIn:=xlValues, LookAt:=xlPart)
If Found Is Nothing Then
Else
xcell.Value = Left(xcell.Value, Len(xcell.Value) - 1)
date_val = xcell.Value 'asign the value to date variable carrier
xcell.Value = date_val 'return it to the cell
End If
Next xcell
Range("D1:D999").NumberFormat = "yyyy-mm-dd" 'do the formatting
End Sub
Hope this works.

Quite simple solution is to parse your data using Mid, Left, Right functions. However, it's not such efficient one would expect but possibly would be helpful. So, the code could be as follows:
xCell = "13-04-08"
xCell = Format(DateSerial(Left(xCell,2),mid(xCell,4,2),Right(xCell,2)),"yyyy-mm-dd")
as a result you get 2013-04-08.
Edit To set appropriate cell formatting try one of the following:
Range("A1").NumberFormat = "yyyy-mm-dd"
or
Range("A1").NumberFormat = "m/d/yyyy"
Where Range("A1") is reference to your cell/range in Excel sheet.

Related

Excel VBA: Error 1004 When Trying To Add Hyperlink

The series of commands seems to result in Runtime Error: 1004 I would like to know what the cause of this error is.
If I do not have the Activesheet.Hyperlinks.add line the cell values get set correctly, just missing the hyperlink... which would make me think I've lost the xCell reference but I've placed debug statements just before the hyperlink.add and it seems to be accessible.
Example URL: http://www.walmart.com/ip/Transformers-Robots-in-Disguise-3-Step-Changers-Optimus-Prime-Figure/185220368
For Each xCell In Selection
Url = xCell.Value
If Url = "" Then
'Do Nothing
ElseIf IsEmpty(xCell) = True Then
'Do Nothing
ElseIf IsEmpty(Url) = False Then
splitArr = Split(Url, "/")
sku = splitArr(UBound(splitArr))
xCell.Value = "https://www.brickseek.com/walmart-inventory-checker?sku=" & sku
'Error happens on next command
ActiveSheet.Hyperlinks.Add Anchor:=xCell, Address:=xCell.Formula
End If
Next xCell
Don't both with .ValueDon't use .Formula:
Sub demo()
Dim s As String, xCell As Range
s = "http://www.walmart.com"
Set xCell = Range("B9")
ActiveSheet.Hyperlinks.Add Anchor:=xCell, Address:=s, TextToDisplay:=s
End Sub
is a typical working example.
There is always another possibilty, that your sheet may be locked and you have to grant permission to do so when locking the sheet.
I know this is not the solution for the problem described here, but the non-deterministic error messages provided by Microsoft VBA is the same. I came here looking for the solution of my problem, an others might bump in this and find my comment relevant.

How to loop Range.Find in VBA?

I am new to VBA so please don't judge too harsh. Having said that below is my issue with Range.Find.
I have a crosstab with a column that has "https" link to pictures; and I have a working VBA to turn these links into actual pictures in each cell for that column. However, my issue is when I add another column into the Crosstab or move column around, my VBA stops working and I end up with my links without actual pictures (since, the picture code is set to the initial column where my links reside).
I figured there should be a way to make it more dynamic by using Range.Find. I have managed to find information on Range.Find, but my code won't work. Is there anyway anyone could help out?
Here is the code:
Function picRng() As Range
Set picRng = ActiveSheet.Range("A1:Z1000")
Set rngFindValue = ActiveSheet.Range("A1:Z1000").Find(what:="http", Lookat:=xlPart)
Do
Set rngFindValue = Search.FindNext(rngFindValue)
Loop While Not rngFindValue is Nothing
End Function
if you want to loop thru all the instances of the search arguments here is the correction of your code
Function picRng() As Range
Set picRng = ActiveSheet.Range("A1:Z1000")
Set rngfindvalue = picRng.Find(what:="http", Lookat:=xlPart)
If Not rngfindvalue Is Nothing Then
rngFirstAddress = rngfindvalue.Address
Do
MsgBox rngfindvalue.Address
Set rngfindvalue = picRng.FindNext(rngfindvalue)
Loop Until rngfindvalue Is Nothing Or rngfindvalue.Address = rngFirstAddress
End If
End Function
You do not need a loop for Find(). If you need the last value in Find(), you need to refer it in the arguments (searchDirection) Something like this will give the last value:
Public Function LocateFind() As Range
Dim rngCell As Range
Dim rngRangeToLookAt As Range
Set rngRangeToLookAt = Range("A1:A100")
Set LocateFind = rngRangeToLookAt.Find("YourValueHere", searchdirection:=xlPrevious)
End Function
Set lx_rangeFind = ActiveSheet.UsedRange.Find(What:=strToFind, LookIn:=xlValues, LookAt:=xlPart)
Set lx_rangeFindFirst = lx_rangeFind
Do
Set lx_rangeFind = ActiveSheet.UsedRange.Find(What:=strToFind, LookIn:=xlValues, LookAt:=xlPart, After:=lx_rangeFind)
'Rest of the code
'now lx_rangeFind has the cell Number
Loop While lx_rangeFindFirst.Address <> lx_rangeFind.Address

Finding a cell based on the header of a section of data, then selecting the last row of that section

I am attempting to find the text of a header row based on the value of a cell relative to the cell that is clicked in. The way I have attempted to do this is follows:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim var1 As Variant
Dim var2 As Variant
Dim var3 As Variant
Dim FormName As String
FormName = "New Form"
Static NewFormCell As Range
Application.ScreenUpdating = False
If Not Intersect(Target, Range("G16:X80")) Is Nothing Then
If Target.Cells.Count = 1 Then
var1 = Cells(Target.Row, 2).Value
var2 = Cells(15, Target.Column).Value
If Not (IsEmpty(var1)) And Not (IsEmpty(var2)) And var2 <> "+" And Target.Interior.ColorIndex <> 2 And Target.Borders(xlEdgeLeft).LineStyle <> xlNone Then
If IsEmpty(Target) Then
Target.Value = "X"
Target.HorizontalAlignment = xlCenter
Target.VerticalAlignment = xlCenter
Target.Font.Bold = True
Dim Header As Range
Set Header = Range("A54:E160").Find(var2, LookIn:=xlValues)
Header.Offset(1, 1).End(xlDown).EntireRow.Select
Dim CopyCell As Range
'Header.End(xlDown).EntireRow.Insert
'Set CopyCell = Header.End(xlDown). [offset?]
'CopyCell.Value = var1
Else
Target.ClearContents
End If
Else
Exit Sub
End If
End If
End If
Application.ScreenUpdating = True
End Sub
The issue is VBA is throwing Run-Time Error 91 ("Object variable or With block variable not set"). It then highlights the last row in that section of code. Since I set that variable in the previous line, I'm not sure why I'm receiving this error or if I'm even going about this the right way.
Any input would be greatly appreciated!
EDIT: I cleared the above issue by searching over a wider range. The cell I wanted to select was merged, but I still assumed the value was stored within column A. But this code still isn't quite doing what I'd like it to:
I want to select the last row in the section (not the last row of data in the sheet, but the last contiguous data in column B), but right now my code is jumping me all the way to the bottom of the sheet.
The problem is that your .Find isn't finding the value. In this case, you can add some code to handle that.
...
Dim Header As Range
Set Header = Range("A59:A159").Find(var2, LookIn:=xlFormulas)
If Header Is Nothing Then
' There's no value found, so do something...
msgbox(var2 & " was not found in the range, will exit sub now."
Exit Sub
End If
MsgBox Header
...
...of course there are myriad ways/things you can do to handle this. If you still want to execute other code, then wrap everything in an If Header is Nothing Then // 'do something // Else // 'other code // End IF type thing.
It really just depends on what you want to do. Again, your error is being caused by the fact that the var2 isn't being found, so just find other things to do in that case.

Finding a value in the range

I am writing a subroutine that looks through a range of cells starting in cell A1 (the range is 1 column wide) containing String values. My sub first finds the entire range and assign it to a Range variable "theForest" to help make searching easier. Then, it looks through each cell in the range until it finds the word “Edward”. If he is found or not, it display the result in a message (stating that he was or was not found).
The code I have so far is this:
With Range("A1")
'this will help find the entire range, since it is only one column I will search by going down
theForest = Range(.Offset(0,0), .End(xlDown)).Select
Dim cell As Range
For Each cell In theForest
If InStr(Edward) Then
Msgbox"He was found"
Else
Msgbox"He was not found sorry"
End If
Next cell
End With
However I am getting numerous errors upon running the program and I think the issue is with the
theForest = Range(.Offset(0,0), .End(xlDown.)).Select
line of code. I would appreciate any guidance into this simple code.
Thank you :)
EDIT: Here is some new code I have come up with:
Dim isFound As Boolean
isFound = False
With Range("A1")
For i = 1 to 500
If .Offset(1,0).Value = "Edward" Then
isFound = True
Exit For
End If
Next
End With
If isFound = True Then
Msgbox " Edward was found"
Else
MsgBox "Edward was not found"
End if
Then again it does not include finding the entire range and assiging it to the range variable theForest.
Dim theForest as Range, f as Range
Set theForest = ActiveSheet.Range(ActiveSheet.Range("A1"), _
ActiveSheet.Range("A1").End(xlDown))
Set f = theForest.Find("Edward", lookat:=xlWhole)
If Not f Is Nothing Then
Msgbox"He was found"
Else
Msgbox"He was not found sorry"
End If

Program stops working on 2nd runthrough

Visual Basic Problem:
Hello Friends,
my problem is pretty complex (although the solution is most likely an easy one):
I've written a small application in Visual Basic. It's a small time management system that has 4 simple functions (on separate buttons):
"Start Work:"
Fetch the current date from System, compare it to a list of dates in an excel table, set current row to the row with the fitting date, and enter the current time in the appropriate cell.
The other functions are "stop work", "start break" and "stop break" and work pretty much the same way.
The application is started by a button embedded in the form and works - so far so good. If I however, start VBA's own debugger and then start the Program again, it fails, because the function that sniffs the correct date out of the list of dates fails to find the correct value. At this point I'm pretty much out of ideas (especially since this is my first VBA project) so I'd be really glad if someone could give me a pointer in the right direction.
Here's the function fetching the date:
Function get_date(time As Date) 'findet das aktuelle Datum in Spalte 2 (Datum)
Dim findDate As Range
On Error Resume Next
Set findDate = Columns(2).Find(Date)
Err.Clear
On Error GoTo 0
If findDate Is Nothing Then
MsgBox "Current Date not on Active Form!"
Else: MsgBox "Current Date is " & Date
MsgBox findDate
Exit Function
End If
End Function
and the function setting the row to the row with the current date
Function get_row(time As Date)
Dim rngSearch As Range, rngFound As Range
Set rngSearch = Range("B5:B18")
Set rngFound = rngSearch.Find(What:=Date, LookIn:=xlValues, LookAt:=xlPart)
If rngFound Is Nothing Then
MsgBox "Aktuelles Datum nicht gefunden - Terminplan erweitern"
Else
get_row = rngFound.row
End If
End Function
As I mentioned both those functionalities work perfectly fine on the first start-up of the form but fail to find (and thus return) a value if I debug and start the Makro again.
The program also has a real time running clock on a timer - maybe that's a factor? I'm totally lost to be honest.
Any criticisms towards the code and how I tackled certain problems are also very welcome - this is my first VBA app ever.
Update:
As requested here's a screenshot of what I assume to be the search ranges:
I'm using the 1904 date system, but changing back to 1900 didn't have any effect.
If anyone is interested, I uploaded the whole Project into my github Stechuhr.xlsm
The relevant file is "Stechuhr.xlsm"
Any further help will be greatly appreciated.
Edit: To clarify - The program stops working, once it has been paused and then resumed. I suspect that the timer function is somehow responsible for this - will do further testing.
Update 2:
As I have been unable to fix this, I simplified my problem as suggested:
Option Explicit
Public Function FindDateRowInColB(TargetDate As Date, TargetSheet As Worksheet) As Long
Dim FoundRange As Range
Set FoundRange = TargetSheet.Columns(2).Find(What:=TargetDate, LookIn:=xlValues, LookAt:=xlPart)
If FoundRange Is Nothing Then
FindDateRowInColB = 0
Else
FindDateRowInColB = FoundRange.Row
End If
End Function
'Test Button 1
Private Sub Test_button_Click()
Dim TestTime As Date
Dim TestSheet As Worksheet
Dim TestRow As Long
Dim pdat_Datum As Date
pdat_Datum = Date
'set references
Set TestSheet = ThisWorkbook.Worksheets("Tabelle1")
'this is our test assertion
TestRow = FindDateRowInColB(pdat_Datum, TestSheet)
'short if statement to display a message based on test results
MsgBox ("TestRow =" & TestRow)
End Sub
' Test Button 2
Private Sub TestButton_2_Click()
Dim active_row As Integer
Dim pdat_aktuellesDatum As Date
Dim TestSheet As Worksheet
pdat_aktuellesDatum = Date
Set TestSheet = ThisWorkbook.Worksheets("Tabelle1")
'set references
Set TestSheet = ThisWorkbook.Worksheets("Tabelle1")
active_row = FindDateRowInColB(pdat_aktuellesDatum, TestSheet)
MsgBox ("Die passende Reihe zum heutigen Datum ist " & active_row)
End Sub
There's the code. It's simply one function and 2 buttons to test it. However, it has the very same problems as my original code - works fine on first startup, but if I ever pause the program and start it again, FindDateRowInColB always returns a value of null. I suppose there might be some memory management issue at work.
If anyone has further input, it will be greatly appreciated.
You could create a lightweight test environment for your functions to make sure they are returning what you'd expect for a few conditions. Here is an example function for finding a date match in column B along with two tests:
Option Explicit
Public Function FindDateRowInColB(TargetDate As Date, TargetSheet As Worksheet) As Long
Dim FoundRange As Range
Set FoundRange = TargetSheet.Columns(2).Find(What:=TargetDate, LookIn:=xlValues, LookAt:=xlPart)
If FoundRange Is Nothing Then
FindDateRowInColB = 0
Else
FindDateRowInColB = FoundRange.Row
End If
End Function
Sub TestFindDateRowFunctionSuccess()
Dim TestTime As Date
Dim TestSheet As Worksheet
Dim TestRow As Long
'set references
Set TestSheet = ThisWorkbook.Worksheets("Sheet1")
TestTime = "4/22/2014"
'this is our test assertion
TestRow = FindDateRowInColB(TestTime, TestSheet)
'short if statement to display a message based on test results
If TestRow = 3 Then
MsgBox ("Test passed! Identified 4/22/2014 in row 3")
Else
MsgBox ("Test failed! Did not identify 4/22/2014 in row 3")
End If
End Sub
Sub TestFindDateRowFunctionFailure()
Dim TestTime As Date
Dim TestSheet As Worksheet
Dim TestRow As Long
'set references
Set TestSheet = ThisWorkbook.Worksheets("Sheet1")
TestTime = "4/1/2014"
'this is our test assertion
TestRow = FindDateRowInColB(TestTime, TestSheet)
'short if statement to display a message based on test results
If TestRow = 0 Then
MsgBox ("Test passed! Date 4/1/2014 was not found so 0 was returned")
Else
MsgBox ("Test failed! Date 4/1/2014 was identified somewhere")
End If
End Sub