In the above column i have unique date.
I have a drop down list where anything can be selected.. so it has 8 permutation(2^3)..So i want to extract probable date based on the selection..Suppose if i select Year as 2020 and day as 19 then i will extract the probable date which match both the condition..Like above picture...
Right now i am using 8 if elseif-=...end if statment...and for loop..Is there any other way to do the same work?? I wanted to write a function which will take (day,month,year,lastrow) as parameter and based on probable date will be calculated..Can anyone give me any idea how to do it?
My code now:
Public Sub ProbableDate(CaseNo As Integer, lastrow As Long)
Dim sh As Worksheet, sh1 As Worksheet
Set sh1 = Worksheets("Dashboard")
Set sh = Worksheets("Logical operation")
Dim Y As String, M As String, D As String
Y = sh1.Cells(4, 1).Value
M = sh1.Cells(4, 2).Value
D = sh1.Cells(4, 3).Value
Dim L As Long, i As Long
L = 2
With sh
.Range("H2:H1048576").Clear
For i = 2 To lastrow
Select Case CaseNo
Case 1
If Year(.Cells(i, 2).Value) = Y Then
.Cells(L, 8).Value = .Cells(i, 2).Value
L = L + 1
End If
Case 2
If MonthName(Month(.Cells(i, 2).Value)) = M Then
.Cells(L, 8).Value = .Cells(i, 2).Value
L = L + 1
End If
Case 3
If Day(.Cells(i, 2).Value) = D Then
.Cells(L, 8).Value = .Cells(i, 2).Value
L = L + 1
End If
Case 4
If Year(.Cells(i, 2).Value) = Y And MonthName(Month(.Cells(i, 2).Value)) = M Then
.Cells(L, 8).Value = .Cells(i, 2).Value
L = L + 1
End If
Case 5
If Year(.Cells(i, 2).Value) = Y And Day(.Cells(i, 2).Value) = D Then
.Cells(L, 8).Value = .Cells(i, 2).Value
L = L + 1
End If
Case 6
If Day(.Cells(i, 2).Value) = D And MonthName(Month(.Cells(i, 2).Value)) = M Then
.Cells(L, 8).Value = .Cells(i, 2).Value
L = L + 1
End If
Case 7
If Day(.Cells(i, 2).Value) = D And MonthName(Month(.Cells(i, 2).Value)) = M And Year(.Cells(i, 2).Value) = Y Then
.Cells(L, 8).Value = .Cells(i, 2).Value
L = L + 1
End If
Case Else
MsgBox "Wrong Info"
End Select
Next i
End With
End Sub
You can simplify your code using a binary lookup table. Each CaseNo matches with a particular set of true/false outcomes for the day, month and year check. These are different to your original mapping, here is the new map:
CaseNo DMY
0 fail
1 D
2 M
3 DM
4 Y
5 D Y
6 MY
7 DMY
And the code:
With sh
.Range("H:H").Clear
For i = 2 To lastrow
OK = 0
If Day(.Cells(i, 2).Value) = D Then OK = OK + 1
If MonthName(Month(.Cells(i, 2).Value)) = M Then OK = OK + 2
If Year(.Cells(i, 2).Value) = Y Then OK = OK + 4
If OK = CaseNo Then
.Cells(L, 8).Value = .Cells(i, 2).Value
L = L + 1
Else
MsgBox "Wrong Info"
End If
Next i
End With
Related
Sub WriteToZeroBasedArray()
Dim E As Integer
Dim rCount As Long: rCount = Worksheets("0618").Cells.SpecialCells(xlLastCell).Row
For E = 9 To 11
Dim V() As Variant ' Note the parentheses!
Dim P() As Variant
Dim N() As Variant
Dim Index As Long
Dim Index_2 As Long
Dim Index_3 As Long
Dim cCount As Long: cCount = Worksheets("0618").Cells.SpecialCells(xlLastCell).Column ' e.g.
Dim c As Long '배열에 값 저장하기
For c = 7 To cCount
If 0 < Worksheets("0618").Cells(E, c).Value And Worksheets("0618").Cells(E, c).Value < 100 Then
ReDim Preserve V(Index)
' A safer way (Option Base related):
'ReDim Preserve V(0 To Index)
V(Index) = Worksheets("0618").Cells(2, c).Value
Index = Index + 1
ReDim Preserve P(Index_2)
P(Index_2) = Worksheets("0618").Cells(4, c).Value
Index_2 = Index_2 + 1
ReDim Preserve N(Index_3)
N(Index_3) = Worksheets("0618").Cells(E, c).Value
Index_3 = Index_3 + 1
End If
Next c
Dim K As Integer
Dim L As Integer
K = UBound(V) '배열의 값 차례로 Sheet2에 넣기
For L = 0 To K
If L < 5 Then
Worksheets("sheet2").Cells(L + 6 + 14 * (E - 9), 1).Value = V(L)
Worksheets("sheet2").Cells(L + 6 + 14 * (E - 9), 2).Value = P(L)
Worksheets("sheet2").Cells(L + 6 + 14 * (E - 9), 3).Value = N(L)
Else
Worksheets("sheet2").Cells(L + 1 + 14 * (E - 9), 5).Value = V(L)
Worksheets("sheet2").Cells(L + 1 + 14 * (E - 9), 6).Value = P(L)
Worksheets("sheet2").Cells(L + 1 + 14 * (E - 9), 7).Value = N(L)
End If
Next
Dim FP As Integer
Dim Sum As Integer
Sum = 0
'수량*단가 구하기
For FP = (6 + 14 * (E - 9)) To (10 + 14 * (E - 9))
Worksheets("sheet2").Cells(FP, 4).Value = Worksheets("sheet2").Cells(FP, 2).Value * Worksheets("sheet2").Cells(FP, 3).Value
Worksheets("sheet2").Cells(FP, 8).Value = Worksheets("sheet2").Cells(FP, 6).Value * Worksheets("sheet2").Cells(FP, 7).Value
'총액 구하기
Sum = Sum + Worksheets("sheet2").Cells(FP, 4).Value + Worksheets("sheet2").Cells(FP, 8).Value
'0 지우기
If Worksheets("sheet2").Cells(FP, 4).Value = 0 Then
Worksheets("sheet2").Cells(FP, 4).ClearContents
End If
If Worksheets("sheet2").Cells(FP, 8).Value = 0 Then
Worksheets("sheet2").Cells(FP, 8).ClearContents
End If
Next
'총액 구하기2
Worksheets("sheet2").Cells(12 + 14 * (E - 9), 8).Value = Sum
'받으실 분
Worksheets("sheet2").Cells(3 + 14 * (E - 9), 2).Value = Worksheets("0618").Cells(E, 3).Value
'주소
Worksheets("sheet2").Cells(3 + 14 * (E - 9), 5).Value = Worksheets("0618").Cells(E, 2).Value
'서식 복사'
Worksheets("sheet3").Range("A1:H13").Copy
Worksheets("sheet2").Range("A" & 15 + 14 * (E - 9)).PasteSpecial
If Index = 0 Then Exit Sub
Next
Debug.Print Join(V, vbLf)
End Sub
I expected this code to be like this
But the result is like this
When E = 9, the code runs exactly the same as I thought, but when E is over 10, it doesn't.
when E = 9, the V array's values and orders are like this [grape, apple], and that's what I wanted.
However, when E = 10, I want the V array's value to be like this [orange]
but the result says it is [ , , orange]
Could someone tell me what's wrong with my code?
For me, the two (different) pictures look like 'Chinese'... So, I cannot refer to them.
No need to use Index, Index2 and Index3. Use only Index and increment it at the second loop end;
'replace this line
Index_3 = Index_3 + 1
'with
Index = Index + 1
' and comment all the previous index incrementations
You must reinitialize the used arrays content and used Index at the first loop end:
'your code...
If Index = 0 Then Exit Sub 'after this existing code line
Erase V: Erase P: Erase N: Index = 0
Next
'Your code
Now, using Redim Preserve to often is bad from memory handling point of view. Please, try firstly ReDim to a value to exceed the necessary number of necessary elements (ReDim V(cCount)) and use only of the end: Redim Preserve V(Index -1). Do the same for the other two used arrays...
Sub WriteToZeroBasedArray()
Dim E As Integer
Dim rCount As Long: rCount =
Worksheets("0618").Cells.SpecialCells(xlLastCell).Row
For E = 9 To rCount
Dim V() As Variant ' Note the parentheses!
Dim P() As Variant
Dim N() As Variant
Dim Index As Long
Dim Index_2 As Long
Dim Index_3 As Long
Dim cCount As Long: cCount = Worksheets("0618").Cells.SpecialCells(xlLastCell).Column ' e.g.
Dim c As Long '배열에 값 저장하기
For c = 7 To cCount
If 0 < Worksheets("0618").Cells(E, c).Value And Worksheets("0618").Cells(E, c).Value < 100 Then
ReDim Preserve V(Index)
' A safer way (Option Base related):
'ReDim Preserve V(0 To Index)
V(Index) = Worksheets("0618").Cells(2, c).Value
Index = Index + 1
ReDim Preserve P(Index_2)
P(Index_2) = Worksheets("0618").Cells(4, c).Value
Index_2 = Index_2 + 1
ReDim Preserve N(Index_3)
N(Index_3) = Worksheets("0618").Cells(E, c).Value
Index_3 = Index_3 + 1
End If
Next c
Dim K As Integer
Dim L As Integer
K = UBound(V) '배열의 값 차례로 Sheet2에 넣기
For L = 0 To K
If L < 5 Then
Worksheets("sheet2").Cells(L + 6 + 14 * (E - 9), 1).Value = V(L)
Worksheets("sheet2").Cells(L + 6 + 14 * (E - 9), 2).Value = P(L)
Worksheets("sheet2").Cells(L + 6 + 14 * (E - 9), 3).Value = N(L)
Else
Worksheets("sheet2").Cells(L + 1 + 14 * (E - 9), 5).Value = V(L)
Worksheets("sheet2").Cells(L + 1 + 14 * (E - 9), 6).Value = P(L)
Worksheets("sheet2").Cells(L + 1 + 14 * (E - 9), 7).Value = N(L)
End If
Next
Dim FP As Integer
Dim Sum As Integer
Sum = 0
'수량*단가 구하기
For FP = (6 + 14 * (E - 9)) To (10 + 14 * (E - 9))
Worksheets("sheet2").Cells(FP, 4).Value = Worksheets("sheet2").Cells(FP, 2).Value * Worksheets("sheet2").Cells(FP, 3).Value
Worksheets("sheet2").Cells(FP, 8).Value = Worksheets("sheet2").Cells(FP, 6).Value * Worksheets("sheet2").Cells(FP, 7).Value
'총액 구하기
Sum = Sum + Worksheets("sheet2").Cells(FP, 4).Value + Worksheets("sheet2").Cells(FP, 8).Value
'0 지우기
If Worksheets("sheet2").Cells(FP, 4).Value = 0 Then
Worksheets("sheet2").Cells(FP, 4).ClearContents
End If
If Worksheets("sheet2").Cells(FP, 8).Value = 0 Then
Worksheets("sheet2").Cells(FP, 8).ClearContents
End If
Next
'총액 구하기2
Worksheets("sheet2").Cells(12 + 14 * (E - 9), 8).Value = Sum
'받으실 분
Worksheets("sheet2").Cells(3 + 14 * (E - 9), 2).Value = Worksheets("0618").Cells(E, 3).Value
'주소
Worksheets("sheet2").Cells(3 + 14 * (E - 9), 5).Value = Worksheets("0618").Cells(E, 2).Value
'서식 복사'
Worksheets("sheet3").Range("A1:H13").Copy
Worksheets("sheet2").Range("A" & 15 + 14 * (E - 9)).PasteSpecial
Erase V, P, N
If Index = 0 Then Exit Sub
Next
Debug.Print Join(V, vbLf)
End Sub
I used "Erase V, P, N" at the last part of this code to make V,P,N into empty arrays, because the code has to repeat from E = 9 to E = Column number and as it repeats, these arrays has to be continuously empty at the last part of the code, to use them again at the next repeat.
But when I run this code, these arrays doesn't become empty. The values are accumulated more and more as the code repeats. I think maybe the code "Erase V, P, N" is the wrong code.
So Could anybody please tell me how to make the the arrays empty?
Could someone help me out with the following code, I thought i figured it out but keep on stranding with the same problem:
Sub history()
nsheets = ActiveWorkbook.Worksheets.Count 'count sheets in workbook
nas_index = ActiveSheet.Index 'index of the activated sheet
nas_LR = Sheets(nas_index).Cells(Sheets(nas_index).Rows.Count, "A").End(xlUp).Row 'count rows of activesheet
For d = 1 To nsheets
If d < nas_index Then
pre_index = Sheets(nas_index - d).Index
pre_LR = Sheets(pre_index).Cells(Sheets(pre_index).Rows.Count, "A").End(xlUp).Row
oldtime = Sheets(d).Cells(1, 6).Value
newwknr = Sheets(nas_index).Cells(1, 7).Value
oldwknr = Sheets(pre_index).Cells(1, 7).Value
StrOldTime = Format(oldtime, "hh:mm:ss")
For n = 3 To nas_LR
prid_new = Sheets(nas_index).Cells(n, 1).Value
For o = 3 To pre_LR
prid_old = Sheets(pre_index).Cells(o, 1).Value
pre_am = Sheets(pre_index).Cells(o, 6).Value
pre_amw = CStr(pre_am) & "(" & StrOldTime & ")" & "(wk: " & oldwknr & ")"
If prid_new = prid_old Then
'Below is not working properly
'------------------------------
re = re & " " & pre_amw
Sheets(nas_index).Cells(n, 10).Value = re
'------------------------------
End If
Next o
Next n
Else
'MsgBox exit loop
Exit For
End If
Next d
'------------------nevermind below
Dim ntime As Date, nStrTime As String
If Not ThisWorkbook.ActiveSheet.Cells(1, 10).Value = "" Then
'-new time
ThisWorkbook.ActiveSheet.Cells(1, 12).Value = Time()
ntime = ThisWorkbook.ActiveSheet.Cells(1, 12).Value
mstrtime = Format(ntime, "hh:mm:ss:ms")
ThisWorkbook.ActiveSheet.Cells(1, 12).Value = mstrtime
'-old time
gettime = ThisWorkbook.ActiveSheet.Cells(1, 10).Value
ThisWorkbook.ActiveSheet.Cells(1, 11).Value = gettime
myStrTime = Format(gettime, "hh:mm:ss:ms")
ThisWorkbook.ActiveSheet.Cells(1, 11).Value = myStrTime
End If
End Sub
The image below is so far what I got (the text in red, is what i wish to have).
My goal is to have the following Check if I bought the same item before (ID). Collect data of this ID and store it in the column History. So that I can see if the product has been price changed over the previous weeks. I can't get the data properly of previous sheets. Instead of getting the following:
item: A B C D or
item: D C B A
I get something like this:
item: A A A A A A B B B B B B C C C C C C D D D D D D or
item: A B C D A B C D A B C D
I think I am failing here:
If prid_new = prid_old Then
'Below is not working properly
'------------------------------
re = re & " " & pre_amw
Sheets(nas_index).Cells(n, 10).Value = re
'------------------------------
End If
Can someone lent me a hand.
I tried looping the worksheets within a grocery item loop with some success.
Historical data is gathered from every worksheet prior to the current worksheet (ActiveSheet) onto the current worksheet.
Option Explicit
Sub costHistory()
Dim i As Long, w As Long, gro As Long, ndx As Long, g As Variant
Dim icost As Double, lcost As Double, dif As String
With ActiveSheet
ndx = ActiveSheet.Index
For i = 3 To .Cells(.Rows.Count, "A").End(xlUp).Row
gro = .Cells(i, "A").Value2
lcost = .Cells(i, "D").Value2
dif = vbNullString
For w = 1 To ndx - 1
With Worksheets(w)
g = Application.Match(gro, .Columns(1), 0)
If Not IsError(g) Then
If .Cells(g, "D").Value2 <> lcost Then
dif = Format(.Cells(g, "D").Value2, "0.00") & _
Format(.Cells(g, "F").Value2, " 0 ") & _
Format(.Cells(1, "F").Value2, "(hh:mm:ss)") & _
Format(.Cells(1, "G").Value2, " (\w\k\:0)") & _
Chr(124) & dif
End If
End If
End With
Next w
If CBool(Len(dif)) Then
.Cells(i, "J") = Left(dif, Len(dif) - 1)
End If
Next i
End With
End Sub
I have table in Sheet1. I can sum up all numeric data of a certain Country.
However I wanted only to sum-up to numbers with the same date.
I have ComboBox for the date. So for example If I choose July 1, it will only add those numbers in July 1.
My desired result if I choose July 1 is the following:
America 24
Brazil 56
Canada 68
screenshot
My code:
Private Sub ComboBox1_Change()
Dim a As Long
Dim b As Long
Dim c As Long
Dim lastrow As Long
a = 0
b = 0
c = 0
lastrow = Sheet1.Cells(Rows.Count, 1).End(xlUp).Row
For i = 2 To lastrow
If Cells(i, 3) = "America" Then
a = Cells(i, 4) + a
ElseIf Cells(i, 3) = "Brazil" Then
b = Cells(i, 4) + b
ElseIf Cells(i, 3) = "Canada" Then
c = Cells(i, 4) + c
End If
Next i
'Range("A16") = a
txtAmerica.Value = a
txtBrazil.Value = b
txtCanada.Value = c
End Sub
Private Sub UserForm_Initialize()
ComboBox1.List = Sheets("Sheet1").Range("G1:G10").Value
End Sub
Assuming the values in column A are dates, and also assuming your locale is using a mm/dd/yyyy date format, this is as simple as just wrapping your summation code in an If statement that checks the date:
For i = 2 To lastrow
If Cells(i, "A").Value = CDate(ComboBox1.Value) Then
If Cells(i, 3) = "America" Then
a = Cells(i, 4) + a
ElseIf Cells(i, 3) = "Brazil" Then
b = Cells(i, 4) + b
ElseIf Cells(i, 3) = "Canada" Then
c = Cells(i, 4) + c
End If
End If
Next i
The following code is working for only when c = 2 ,however I want it to work for other values as well. Below is the Excel table on which I want to run it.
Date PickupCost StorageCost DeliveryCost
1/1/2017 140 35 0
1/8/2017 80 20 0
1/10/2017 0 0 149
1/30/2017 35 8 0
I want to fill data of each date missing but only the value at column 3 (StorageCost) needs to be same in other missing date values as previous day's StorageCost value.
Dim j, p, w, c As Long
Dim date1, date2 As Date
j = Cells(Rows.Count, 1).End(xlUp).Row
w = 2
For c = w To j
date1 = Range("A" & w).Value
date2 = Range("A" & (w + 1)).Value
p = DateDiff("d", date1, date2)
For w = 2 To p
Range("A" & (c + 1)).EntireRow.Insert
ActiveSheet.Cells(c + 1, 1).Value = (ActiveSheet.Cells(c, 1).Value) + 1
ActiveSheet.Cells(c + 1, 2).Value = 0
ActiveSheet.Cells(c + 1, 3).Value = ActiveSheet.Cells(c, 3).Value
ActiveSheet.Cells(c + 1, 4).Value = 0
c = c + 1
Next w
w = w + 1
ActiveSheet.Range("A1").Select
j = Cells(Rows.Count, 1).End(xlUp).Row
Next c
Your main problem is that once you defined your For c = w To j loop then it will only run until it reaches value j had when you defined the for loop.
If you want an endpoint to the loop that adapts to the runtime changing number of rows, you should use a Do Until loop, like this:
Dim p As Long
Dim c, w As Integer
Dim date1, date2 As Date
c = 2
Do Until c = Cells(Rows.Count, 1).End(xlUp).Row
date1 = Range("A" & c).Value
date2 = Range("A" & (c + 1)).Value
p = DateDiff("d", date1, date2)
For w = c To c + p - 2
Range("A" & (w + 1)).EntireRow.Insert
ActiveSheet.Cells(w + 1, 1).Value = (ActiveSheet.Cells(c, 1).Value) + 1
ActiveSheet.Cells(w + 1, 2).Value = 0
ActiveSheet.Cells(w + 1, 3).Value = ActiveSheet.Cells(c, 3).Value
ActiveSheet.Cells(w + 1, 4).Value = 0
c = c + 1
Next w
c = c + 1
Loop