Hi I am writing Excel VBA code. I just wanted to do subtraction for this kind of table
But I can't figure out how to do that using VBA. Is the code below correct?
Sub OperationO()
Dim OE As Integer
Dim i As Integer
For i = 3 To Range("F6")
Cells(6, i).Value = Cells(2, i).Value - Cells(4, i)
Next i
End Sub
You should really use formulas for something like this, but if you insists on VBA, here it goes.
Whenever you write code for VBA or any similar languages, read what you are writing, what it should/needs to do, as you read it out loud many times the errors pop up. Think of the comments below as "me reading as I write."
Sub OperationO()
'Initiate a Variable type Integer for number storage
Dim OE as Integer
'Initiate another variable same type to use in the loop
Dim i as Integer
'Start a loop from 3 to 6 (because these are the columns you are working with)
For i = 3 to 6
'Set the value in Column "i" on Row 6 to the value in Row 2 minus Row 4 in the same column
'Now here is the thing, when you subtract a negative number, you are adding it, crazy math rules i know, so if the number is negative, you need to Add instead.
Cells(6, i).Value = (Cells(2, i).Value + Cells(4, i).Value)
'If both cells don't contain a number, this will fail, additional checks may help, like IsNumber
Next i
'Its the end of the Sub and you never used the Variable OE, it was declared for nothing.
End Sub
Related
The main problem started when I wanted to "convert to number" by the green triangle (I know I can do it by hand, but there are a lot of cells like that and in the future I only want to use code).
So I wanted to do it by code, and I came across with this code that helps, but I have a problem with the number format which removes the decimal numbers.
Sub Valor3()
Dim LastRow As Long, i As Long
LastRow = Sheets("Hoja3").Range("A" & Rows.Count).End(xlUp).Row
'Sheets("Hoja3").Range("A1:A" & LastRow).NumberFormat = "# ##0,00"
For i = 1 To LastRow
If Val(Sheets("Hoja3").Range("A" & i).Value) <> 0 Then _
Sheets("Hoja3").Range("A" & i).Formula = _
Val(Sheets("Hoja3").Range("A" & i).Value)
Next i
End Sub
I've been trying many formats but none of them seems to help.
It might be because here we use the comma as a decimal separator and there is no miles separator.
What number format would help me?
The issue is that you use Val function in combination with a non-us-english decimal separator, which is not a proper solution to your issue.
The Val function recognizes only the period ( .) as a valid decimal separator. When different decimal separators are used, as in international applications, use CDbl instead to convert a string to a number.
Source: Microsoft documentation Val function.
Since the Val function does not convert a text into a value but extracts
The Val function only works with a dot . as decimal separator.
Example:
Val("2.55") 'will return 2.55 as number
Val("2,55") 'will return 2 as number (because it cuts off all text and the comma is not considered as decimal separator)
To get rid of the green triangle and convert a number that is saved as text into a real number properly, use the following:
Option Explicit
Public Sub ConvertNumberAsTextIntoRealNumber()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Hoja3")
Dim LastRow As Long
LastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
With ws.Range("A1", "A" & LastRow)
.NumberFormat = "# ##0.00" 'set your desired number format
.Value = .Value 'this will in most cases already convert to real numbers.
End With
'But if your numbers are hard coded to text and begin with a `'` you need the following additionally:
Dim iRow As Long
For iRow = 1 To LastRow
With ws.Cells(iRow, "A")
If IsNumeric(.Value) Then 'can the value be interpreted as a number
If .Value <> 0 Then 'is the value not zero
.Value = CDbl(.Value) 'then convert it into a real number
End If
End If
End With
Next iRow
End Sub
I know you are looking for VBA solution, but here's a small Excel trick that you might find useful:
Enter 1 (numeric value) somewhere in the file and copy it:
Select your range (A1:A6) and go to Paste > Paste Special > select Multiply:
The final result is all your text values being converted to numbers:
The same trick will work with other combinations, e.g. Operation: Add while having 0 copied, etc.
There seems to be lots of similar questions but nothing that quite seems to answer this one.
I have created the below sub to convert a column of text to dates. It works in some scenarios, i.e. where the date has 8 characters such as 10022017, but not if the value has 7 characters such as 1022017.
Any ideas appreciated.
Sub convertDate()
'Find the last Row with data in a Column
Dim lastRow As Long
Dim i As Long
With ActiveSheet
lastRow = .Cells(.Rows.Count, ColumnSelect).End(xlUp).Row
End With
'convert column from string to date
For i = RowSelect To lastRow
Cells(i, ColumnSelect).Value = Format(Cells(i, ColumnSelect).Value, "00/00/0000")
Next i
End Sub
Hi again all, still having a few problems, the ideal formula seems to be =DATEVALUE(TEXT(A1,"00-00-0000")) if for example A1 = e.g. 02022017. Still haven't found the best way to do this with VBA as everything seems to run up against the truncated zeros problem. Thanks in advance
If your format is going to be consistent then try this.
This adds a 0 before Cells(i, ColumnSelect).Value when there are 7 characters.
For i = RowSelect To lastRow
Select Case Len(Trim(Cells(i, ColumnSelect).Value))
Case 8
Cells(i, ColumnSelect).Value = Format(Cells(i, ColumnSelect).Value, "00/00/0000")
Case 7
Cells(i, ColumnSelect).Value = Format("0" & _
Cells(i, ColumnSelect).Value, "00/00/0000")
End Select
Next i
But be careful with numbers like 1122017... this can be 11/2/2017 or 1/12/2017
Edit
Looking at 10022017, I realised that 1122017 will be 1/12/2017 and not 11/2/2017 as your mm zeros are not getting truncated.
OP wants a formula as well
=IF(LEN(A1)=8,TEXT(DATEVALUE(LEFT(A1,2)&"/"&MID(A1,3,2)&"/"&RIGHT(A1,4)),"dd/mm/yyyy"),TEXT(DATEVALUE(LEFT(A1,1)&"/"&MID(A1,2,2)&"/"&RIGHT(A1,4)),"dd/mm/yyyy"))
I am trying to create a function or functions that can sum daily hours from time cards for each client to come up with the total hours worked per day. Each client has it's own sheet inside of a single workbook.
Currently, I have a function that determines the sheet that goes with the first client (the third sheet in the workbook):
Function FirstSheet()
Application.Volatile
FirstSheet = Sheets(3).Name
End Function
And one to find the last sheet:
Function LastSheet()
Application.Volatile
LastSheet = Sheets(Sheets.Count).Name
End Function
The part that I am having trouble with it getting these to work within the sum function.
=sum(FirstSheet():LastSheet()!A1
That is basically what I want to accomplish. I think the problem is that I don't know how to concatenate it without turning it into a string and it doesn't realize that it is sheet and cell references.
Any help would be greatly appreciated.
So, an example formula would look like this:
=SUM(Sheet2!A1:A5,Sheet3!A1:A5,Sheet4!A1:A5)
That would sum Sheet2-Sheet4, A1:A5 on all sheets.
Is there a reason you need to write the VBA code to do this?
Can't you just enter it as a formula once?
Also, if you're going to the trouble of writing VBA to generate a formula, it may make more sense to just do the sum entirely in VBA code.
If not, try this:
Sub GenerateTheFormula()
Dim x, Formula
Formula = "=SUM(" 'Formula begins with =SUM(
For x = 3 To Sheets.Count
Formula = Formula & Sheets(x).Name & "!A1," 'Add SheetName and Cell and Comma
Next x
Formula = Left(Formula, Len(Formula) - 1) & ")" 'Remove trailing comma and add parenthesis
Range("B1").Formula = Formula 'Where do you want to put this formula?
End Sub
Results:
The functions return strings and not actual worksheets. The Worksheet does not parse strings well. So add a third function that uses the Evaluate function:
Function MySum(rng As Range)
MySum = Application.Caller.Parent.Evaluate("SUM(" & FirstSheet & ":" & LastSheet & "!" & rng.Address & ")")
End Function
Then you would simply call it: MySum(A1)
It uses the other two function you already have created to create a string that can be evaluated as a formula.
I didn't understand ur question completely but As I understood u have different sheets of different clients which contains supoose column 1 date and column 2
contains hours on that particular date wise hours and a final sheet which column1 contains name of client and column 2 contains total hoursPlease try it
Sub countHours()
Dim last_Row As Integer
Dim sum As Double
sum = 0
'Because I know number of client
For i = 1 To 2 'i shows client particular sheet
last_Row = Range("A" & Rows.Count).End(xlUp).Row
Sheets(i).Activate
For j = 2 To last_Row
'In my Excel sheet column 1 contains dates and column 2 contains number of hours
sum = sum + Cells(j, 2)
'MsgBox sum
Next j
'Sheet 3 is my final sheet
ThisWorkbook.Sheets(3).Cells(i + 1, 2).Value = sum
sum = 0
Next i
End Sub
Happy Coding :
I'm using Excel to generate numbers from a basic formula that has 2 variables. I have 600 numbers (specifically coordinates), that I need to generate 13 new numbers from each (so I'll need a total of 8400 values/rows for each X & Y). Since the formula will need to change every 14 rows to a new absolute cell, I am having a hard time thinking of how to accomplish this in Excel using VBA.
My current thought is this:
Add rows to accommodate for the new values.
Fill down columns C and D with the repeating pattern of values.
Create a loop that runs the formula for 14 rows then repeats, keeping the absolute value based on position (?).
Admittedly, I am not a pro at VBA, so any help on how to accomplish this task is greatly appreciated.
See screen grab of data, below, for an example.
Snippet of Data
I used this code to get 13 new rows for my values.
Sub AddRows()
ScreenUpdating = False
With ActiveSheet
lastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
End With
Dim AddRows As Integer: AddRows = 13
Dim i As Integer: i = lastRow
Do While i <> 1
Rows(i & ":" & i + AddRows - 1).Insert
i = i - 1
Loop
ScreenUpdating = True
End Sub
In my VBA code, I am attempting to do the following:
Set the Active Cell to C11
Add the number 1 to an id
Prompt the user for a name and enter that in the cell to the right
Go to the next row & repeat.
However, the number that is entered is another one, not a 2, 3, 4....
Instead, I get the following:
1 Name 1
1 Name 2
1 Name 3
and I want:
1 Name 1
2 Name 2
3 Name 3
Here is the code, what am I missing?
Sub AddToSheet()
Dim id As Integer
Dim name As String
Worksheets("sheet1").Activate
ActiveCell.Range("C11").Select
For Each mycell In Range("C11:C20")
id = mycell.Select
ActiveCell.Value = 1
id = id + 1
name = mycell.Offset(0, 1).Select
name = InputBox("what is the film?")
ActiveCell.Value = name
Next mycell
End Sub
It's not what you're missing, it's what you are getting wrong - some pointers:
1) There is rarely (dare I say, never) a need to use .Select in Excel VBA, you can access an object's properties directly without selecting the actual object. This is generally considered bad practice.
2) id = mycell.Select is not a valid statement, the .Select method merely sets focus to an object(s) it is not used to return a value.
3) ActiveCell.Value = 1 <-- This is where you are going wrong as far as your question is concerned
4) Your code increments the value of id with each loop, but you do not actually use this value for anything - another hint at why it's not working as you expected.
5) Try and use indentation on your code, this will make it much easier for you (and others) to follow the logic of your code and help to ensure you have closed all 'block' statements.
Try this code instead:
Sub AddToSheet()
Dim i As Integer
For i = 11 To 20
Range("C" & i & ":D" & i).Value = Array(i - 10, InputBox("What is the film?"))
Next i
End Sub
This accesses the .Value method of the Range object without actually selecting or activating it, and so we skip a couple of lines of code straight away. Secondly - I've used an Array to assign the values so that we can do it all in one line of code - this is nothing groundbreaking and you won't see any difference in speed/performance but it's hopefully something for you to look at and possibly manipulate for your own uses in the future.