I am a VBA beginner and I am having trouble automating a chart based on the number of series that it will have. I have the following input:
I need to create a stacked chart as above and I wrote the code below, however it seems the macro is not seeing the 4th series. The other option is to set rng as Sd1:SH" & CountT + 1 and ignore rng2, however this option uses the ID values plus the first series as the values of axis X. Can someone please tell me what I am doing wrong?
Sub GraphPs()
Dim CountT As Integer
Dim cht As Chart
Range("sd1:sh200").Select
Selection.ClearContents
CountB = 0
CountC = 0
CountD = 0
CountT = Range("B" & Rows.Count).End(xlUp).Row - 1
Set RngBegin = Range("c2:c" & CountT + 1)
Set RngEnd = Range("d2:d" & CountT + 1)
Mindate = Application.WorksheetFunction.Min(RngBeginDate)
For i = 1 To CountT
'calculate series 2, 3 and 4. Series 1 is the values of the input in column C
Date1 = Cells(i + 1, 3)
Date2 = Cells(i + 1, 4)
If Date1 = Empty And Date2 = Empty Then
NumberD = Empty
End If
If Date1 <> Empty And Date2 <> Empty Then
NumberD = Date2 - Date1
End If
If Date1 <> Empty And Date2 = Empty Then
NumberD = Date - Date1
End If
If NumberD >= 365 Then
Cells(i + 1, 500) = NumberD
Cells(i + 1, 501) = 0
Cells(i + 1, 502) = 0
CountB = CountB + 1
End If
If NumberD >= 365 / 2 And NumberD < 365 Then
Cells(i + 1, 500) = 0
Cells(i + 1, 501) = NumberD
Cells(i + 1, 502) = 0
CountC = CountC + 1
End If
If NumberD < 365 / 2 Then
Cells(i + 1, 500) = 0
Cells(i + 1, 501) = 0
Cells(i + 1, 502) = NumberD
CountD = CountD + 1
End If
Cells(i + 1, 498) = Cells(i + 1, 2)
Cells(i + 1, 499) = Cells(i + 1, 3)
Next
'Delete old chart
Application.ScreenUpdating = False
On Error Resume Next
ActiveSheet.ChartObjects.Delete
On Error GoTo 0
Application.ScreenUpdating = True
'Create graph
Set cht = Sheets("Sheet1").ChartObjects.Add(38, 38, 400, 400).Chart
Set Rng = Range("Se1:SH" & CountT + 1)
Set Rng2 = Range("Sd2:sd" & CountT + 1)
'Writes legend
Cells(1, 498) = " "
Cells(1, 499) = "A"
Cells(1, 500) = "B"
Cells(1, 501) = "C"
Cells(1, 502) = "D"
With cht
.ChartType = xlBarStacked
.HasTitle = True
.HasLegend = True
.SetSourceData Source:=Rng, PlotBy:=xlColumns
With Sheets("Sheet1").ChartObjects(1)
.Left = Range("b38").Left
.Top = Range("b" & CountT + 5).Top
.Width = 900
End With``
.Axes(xlValue, xlPrimary).MinimumScale = Mindate
.Axes(xlValue).TickLabels.NumberFormat = "mm-dd-yyyy"
.Axes(xlValue).MajorUnit = 365.25
.Axes(xlValue, xlPrimary).HasMajorGridlines = True
cht.ChartGroups(1).GapWidth = 500
cht.ChartGroups(1).Overlap = 0
.SeriesCollection(1).Select
With Selection.Format.Fill
.Visible = msoTrue
.ForeColor.RGB = RGB(255, 255, 255)
.Transparency = 0
.Solid
End With
If CountB <> 0 Then
.SeriesCollection(2).Select
With Selection.Format.Fill
.Visible = msoTrue
.ForeColor.RGB = RGB(177, 160, 199)
End With
End If
If CountC <> 0 Then
.SeriesCollection(3).Select
With Selection.Format.Fill
.Visible = msoTrue
.ForeColor.RGB = RGB(255, 192, 0)
End With
End If
'here is the error in the code
If CountD <> 0 Then
.SeriesCollection(4).Select
With Selection.Format.Fill
.Visible = msoTrue
.ForeColor.RGB = RGB(196, 215, 155)
End With
End If
'Format chart
With .ChartTitle
.Characters.Font.Bold = True
.Characters.Font.Size = 18
.Characters.Font.Color = RGB(0, 0, 0)
.Text = "POR"
End With
With .PlotArea.Border
.LineStyle = xlContinuous
.Weight = xlThin
.Color = RGB(0, 0, 0)
End With
' add chart area border
With .ChartArea.Border
.LineStyle = xlDot
.Weight = xlThin
.Color = RGB(0, 0, 0)
End With
End With
Range("a37:a37").Select
End Sub
Related
I have some confusion about excel vba. My aim is to determine which shipments are exceed of the daily carton pick capacity or pallet pick capacity. Each month has different carton and pallet amount.
For Each cell In Range("AB2:AB10000")
For i = 2 To 10000
If Mid(cell.Value, 4, 2) = "01" Then
toplam_karton_ocak = toplam_karton_ocak - Cells(i, 20)
toplam_palet_ocak = toplam_palet_ocak - cell(i, 19)
If toplam_palet_ocak < 0 Or toplam_karton_ocak < 0 Then
MsgBox (Cells(i, 1).Value & " nolu shipment kapasiteyi aşmaktadır.")
End If
I used "for each " to check every cell in the column and I used 12 "if" conditions to assign date to the right capacity. I tried to decrease the capacity when every shipment came. My aim is that if pallet or carton pick is less than zero, giving a message on the screen.
Mid(cell.Value, 4, 2) --> It takes 4th and 5th digits of the day. i.e the date is "22.05.2020".It receives "05" and that means "may"
My problem is I could not do this for every day. I just did it for month but it is useless because i have to check it separately for every single day. What should i do?
You can find the full code below:
Sub New_DC()
New_DC Makro
Range("Z1").Select
ActiveCell.FormulaR1C1 = "BOOKING ONLY DATES"
Range("Z2").Select
ActiveCell.FormulaR1C1 = "=LEFT([#[BOOKING_DATE_OR]],8)"
Range("AA1").Select
ActiveCell.FormulaR1C1 = "Column1 "
Range("AA2").Select
ActiveCell.FormulaR1C1 = _
"=DATE(RIGHT([#[BOOKING ONLY DATES]],4),MID([#[BOOKING ONLY DATES]],3,2),LEFT([#[BOOKING ONLY DATES]],2))"
Range("AB1").Select
ActiveCell.FormulaR1C1 = "New DC"
Range("AB2").Select
ActiveCell.FormulaR1C1 = _
"=IF(RC[-14]=""1-YES"",IF(ISBLANK([#[Sum of Carrier Lead Time]]),[#[Column1 ]]-[#[Sum of TRANSPORT_DURATION]],[#[Column1 ]]-[#[Sum of Carrier Lead Time]]),IF(ISBLANK([#[Sum of Carrier Lead Time]]),[#[END_TIME_UTC]]-[#[Sum of TRANSPORT_DURATION]],[#[END_TIME_UTC]]-[#[Sum of Carrier Lead Time]]))"
Columns("AB:AB").Select
Selection.NumberFormat = "m/d/yyyy"
Columns("Z:AA").Select
Selection.EntireColumn.Hidden = True
Range("AE11").Select
Range("Table1[[#Headers],[New DC]]").Select
ActiveWorkbook.Worksheets("Data").ListObjects("Table1").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("Data").ListObjects("Table1").Sort.SortFields.Add2 _
Key:=Range("Table1[[#Headers],[New DC]]"), SortOn:=xlSortOnValues, Order _
:=xlAscending, DataOption:=xlSortNormal
With ActiveWorkbook.Worksheets("Data").ListObjects("Table1").Sort
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Range("AC2").Select
ActiveCell.FormulaR1C1 = _
"=IF([#[Booking_Appointment_Made (groups)]]=""1-YES"",1,0)"
Range("AC2").Select
Range(Selection, Selection.End(xlDown)).Select
ActiveWorkbook.Worksheets("Data").ListObjects("Table1").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("Data").ListObjects("Table1").Sort.SortFields.Add2 _
Key:=Range("AC2"), SortOn:=xlSortOnValues, Order:=xlDescending, _
DataOption:=xlSortNormal
With ActiveWorkbook.Worksheets("Data").ListObjects("Table1").Sort
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Columns("AC:AC").Select
Selection.EntireColumn.Hidden = True
Range("AB2").Select
Dim toplam_karton_ocak As Long, toplam_karton_subat As Long, toplam_karton_mart As Long, toplam_karton_nisan As Long
Dim toplam_karton_mayis As Long, toplam_karton_haziran As Long, toplam_karton_temmuz As Long, toplam_karton_agustos As Long
Dim toplam_karton_eylul As Long, toplam_karton_ekim As Long, toplam_karton_kasim As Long, toplam_karton_aralik As Long
Dim toplam_palet_ocak As Integer, toplam_palet_subat As Integer, toplam_palet_mart As Integer, toplam_palet_nisan As Integer
Dim toplam_palet_mayis As Integer, toplam_palet_haziran As Integer, toplam_palet_temmuz As Integer, toplam_palet_agustos As Integer
Dim toplam_palet_eylul As Integer, toplam_palet_ekim As Integer, toplam_palet_kasim As Integer, toplam_palet_aralik As Integer
toplam_karton_ocak = 15000
toplam_palet_ocak = 300
toplam_karton_subat = 15000
toplam_palet_subat = 300
toplam_karton_mart = 15000
toplam_palet_mart = 300
toplam_karton_nisan = 17000
toplam_palet_nisan = 400
toplam_karton_mayis = 17500
toplam_palet_mayis = 600
toplam_karton_haziran = 18000
toplam_palet_haziran = 300
toplam_karton_temmuz = 20000
toplam_palet_temmuz = 300
toplam_karton_agustos = 25000
toplam_palet_agustos = 500
toplam_karton_eylul = 42000
toplam_palet_eylul = 900
toplam_karton_ekim = 35000
toplam_palet_ekim = 750
toplam_karton_kasim = 27000
toplam_palet_kasim = 750
toplam_karton_aralik = 22500
toplam_palet_aralik = 750
For Each cell In Range("AB2:AB10000")
For i = 2 To 10000
If Mid(cell.Value, 4, 2) = "01" Then
toplam_karton_ocak = toplam_karton_ocak - Cells(i, 20)
toplam_palet_ocak = toplam_palet_ocak - cell(i, 19)
If toplam_palet_ocak < 0 Or toplam_karton_ocak < 0 Then
MsgBox (Cells(i, 1).Value & " nolu shipment kapasiteyi aşmaktadır.")
End If
ElseIf Mid(cell.Value, 4, 2) = "02" Then
toplam_karton_subat = toplam_karton_subat - Cells(i, 20)
toplam_palet_subat = toplam_palet_subat - Cells(i, 19)
If toplam_palet_subat < 0 Or toplam_karton_subat < 0 Then
MsgBox (Cells(i, 1).Value & " nolu shipment kapasiteyi aşmaktadır.")
End If
ElseIf Mid(cell.Value, 4, 2) = "03" Then
toplam_karton_mart = toplam_karton_mart - Cells(i, 20)
toplam_palet_mart = toplam_palet_mart - Cells(i, 19)
If toplam_palet_mart < 0 Or toplam_karton_mart < 0 Then
MsgBox (Cells(i, 1).Value & " nolu shipment kapasiteyi aşmaktadır.")
End If
ElseIf Mid(cell.Value, 4, 2) = "04" Then
toplam_karton_nisan = toplam_karton_nisan - Cells(i, 20)
toplam_palet_nisan = toplam_palet_nisan - Cells(i, 19)
If toplam_palet_nisan < 0 Or toplam_karton_nisan < 0 Then
MsgBox (Cells(i, 1).Value & " nolu shipment kapasiteyi aşmaktadır.")
End If
ElseIf Mid(cell.Value, 4, 2) = "05" Then
toplam_karton_mayis = toplam_karton_mayis - Cells(i, 20)
toplam_palet_mayis = toplam_palet_mayis - Cells(i, 19)
If toplam_palet_mayis < 0 Or toplam_karton_mayis < 0 Then
MsgBox (Cells(i, 1).Value & " nolu shipment kapasiteyi aşmaktadır.")
End If
ElseIf Mid(cell.Value, 4, 2) = "06" Then
toplam_karton_haziran = toplam_karton_haziran - Cells(i, 20)
toplam_palet_haziran = toplam_palet_haziran - Cells(i, 19)
If toplam_palet_haziran < 0 Or toplam_karton_haziran < 0 Then
MsgBox (Cells(i, 1).Value & " nolu shipment kapasiteyi aşmaktadır.")
End If
ElseIf Mid(cell.Value, 4, 2) = "07" Then
toplam_karton_temmuz = toplam_karton_temmuz - Cells(i, 20)
toplam_palet_temmuz = toplam_palet_temmuz - Cells(i, 19)
If toplam_palet_temmuz < 0 Or toplam_karton_temmuz < 0 Then
MsgBox (Cells(i, 1).Value & " nolu shipment kapasiteyi aşmaktadır.")
End If
ElseIf Mid(cell.Value, 4, 2) = "08" Then
toplam_karton_agustos = toplam_karton_agustos - Cells(i, 20)
toplam_palet_agustos = toplam_palet_agustos - Cells(i, 19)
If toplam_palet_agustos < 0 Or toplam_karton_agustos < 0 Then
MsgBox (Cells(i, 1).Value & " nolu shipment kapasiteyi aşmaktadır.")
End If
ElseIf Mid(cell.Value, 4, 2) = "09" Then
toplam_karton_eylul = toplam_karton_eylul - Cells(i, 20)
toplam_palet_eylul = toplam_palet_eylul - Cells(i, 19)
If toplam_palet_eylul < 0 Or toplam_karton_eylul < 0 Then
MsgBox (Cells(i, 1).Value & " nolu shipment kapasiteyi aşmaktadır.")
End If
ElseIf Mid(cell.Value, 4, 2) = "10" Then
toplam_karton_ekim = toplam_karton_ekim - Cells(i, 20)
toplam_palet_ekim = toplam_palet_ekim - Cells(i, 19)
If toplam_palet_ekim < 0 Or toplam_karton_ekim < 0 Then
MsgBox (Cells(i, 1).Value & " nolu shipment kapasiteyi aşmaktadır.")
End If
ElseIf Mid(cell.Value, 4, 2) = "11" Then
toplam_karton_kasim = toplam_karton_kasim - Cells(i, 20)
toplam_palet_kasim = toplam_palet_kasim - Cells(i, 19)
If toplam_palet_kasim < 0 Or toplam_karton_kasim < 0 Then
MsgBox (Cells(i, 1).Value & " nolu shipment kapasiteyi aşmaktadır.")
End If
ElseIf Mid(cell.Value, 4, 2) = "12" Then
toplam_karton_aralik = toplam_karton_aralik - Cells(i, 20)
toplam_palet_aralik = toplam_palet_aralik - Cells(i, 19)
If toplam_palet_aralik < 0 Or toplam_karton_aralik < 0 Then
MsgBox (Cells(i, 1).Value & " nolu shipment kapasiteyi aşmaktadır.")
End If
End If
Next i
Next cell
Columns("AB:AB").Select
Range("AF6").Select
End Sub
Thanks for your help :)
I am trying to create a chart with VBA, collecting data with the code from a table (not selecting directly the data in the worksheet but doing some internal calculation). My problem is that it does not draw correctly the X-axis (it should be showing just 12.19, 01.20, 02.20):
Do you know how to adjust this (as each month has a different amount of days...)?
This is my code:
Function ChartGenerator(mes As Double, contrato As String, kpi As String)
Dim listax() As Double
Dim listay() As Double
Dim numeelem As Integer
numeelem = 0
last_row = Worksheets("Data").Range("A" & Rows.Count).End(xlUp).row
For i = 2 To last_row
If Worksheets("Data").Cells(i, 8).value <= mes And Worksheets("Data").Cells(i, 4).value = contrato _
And Worksheets("Data").Cells(i, 5).value = kpi Then
numeelem = numeelem + 1
End If
Next i
ReDim listax(numeelem - 1)
ReDim listay(numeelem - 1, 1)
numeelem = 0
For i = 2 To last_row
If Worksheets("Data").Cells(i, 8) <= mes And Worksheets("Data").Cells(i, 4) = contrato _
And Worksheets("Data").Cells(i, 5) = kpi Then
numeelem = numeelem + 1
listax(numeelem - 1) = Worksheets("Data").Cells(i, 8).value **'Those are dates**
listay(numeelem - 1, 0) = Worksheets("Data").Cells(i, 6).value
listay(numeelem - 1, 1) = Worksheets("Data").Cells(i, 7).value
End If
Next i
Dim ydata As Variant
ReDim ydata(numeelem - 1)
Charts.Add
With ActiveChart
.ChartArea.ClearContents
.ChartType = xlXYScatterLines
.ChartStyle = 241 'para cambiar el estilo, usar este
For k = 1 To 2
For j = 0 To numeelem - 1
ydata(j) = listay(j, k - 1)
Next j
.SeriesCollection.NewSeries
.SeriesCollection(k).XValues = listax
.SeriesCollection(k).Values = ydata
.SeriesCollection(k).Name = Worksheets("Data").Cells(1, 6 - 1 + k).value '"prueba" & i 'ID(i, 1)
If k = 2 Then
.SeriesCollection(k).Format.Line.DashStyle = msoLineSysDash
End If
For j = 1 To numeelem
With .SeriesCollection(k).Points(j)
.ApplyDataLabels
.DataLabel.Text = listay(j - 1, k - 1)
End With
Next j
Next k
.HasTitle = True
.Legend.Format.TextFrame2.TextRange.Font.Size = 14
.ChartTitle.Text = contrato & " - " & kpi
With .Axes(xlCategory, xlPrimary)
.HasTitle = True
.AxisTitle.Characters.Text = "Date"
.AxisTitle.Font.Size = 14
.AxisTitle.Font.Name = "calibri"
.CategoryType = xlTimeScale
.MinimumScale = listax(0) - 0.0000000001
.MaximumScale = listax(numeelem - 1) + 1
.MinorUnit = 31
.MajorUnit = 31
.TickLabels.NumberFormat = "mmmm-yy"
End With
With .Axes(xlValue, xlPrimary)
.HasTitle = True
.AxisTitle.Text = "Amount of €"
.AxisTitle.Font.Size = 14
.AxisTitle.Font.Name = "calibri"
End With
End With
End Function
When I execute the following code, a black command window opens and it will flicker until the time all devices pings. How can I run it silently?
Sub PING()
Application.ScreenUpdating = False
Dim strTarget, strPingResult, strInput, wshShell, wshExec
With Sheets(1)
shlastrow = .Cells(Rows.Count, "B").End(xlUp).Row
Set shrange = .Range("B3:B7" & shlastrow)
End With
For Each shCell In shrange
strInput = shCell.Text
If strInput <> "" Then
strTarget = strInput
setwshshell = CreateObject("wscript.shell")
Set wshExec = wshShell.exec("ping -n 2 -w 5 " & strTarget)
strPingResult = LCase(wshExec.stdout.readall)
If InStr(strPingResult, "reply from") Then
shCell.Offset(0, 1).Value = "Reachable"
shCell.Offset(0, 2).Value = "Time"
Else
shCell.Offset(0, 1).Value = "UnReachable"
shCell.Offset(0, 2).Value = "Reachable"
End If
End If
Next shCell
End Sub
Here is the code for that
Sub Do_ping()
With ActiveWorkbook.Worksheets(1)
n = 0
Row = 2
Do
If .Cells(Row, 1) <> "" Then
If IsConnectible(.Cells(Row, 1), 2, 100) = True Then
n = n + 1
Cells(Row, 1).Interior.Color = RGB(0, 255, 0)
Cells(Row, 1).Font.FontStyle = "bold"
Cells(Row, 1).Font.Size = 14
Cells(Row, 2).Interior.Color = RGB(0, 255, 0)
Cells(Row, 2).Value = Time
'Call siren
Else:
n = n + 1
'Cells(Row, 2).Formula = "=NOW()-" & CDbl(Now())
Cells(Row, 1).Interior.Color = RGB(255, 0, 0)
Cells(Row, 3).Value = DateDiff("h:mm:ss", Cells(Row, 2), Now())
End If
End If
Row = Row + 1
Loop Until .Cells(Row, 1) = ""
End With
End Sub
Function IsConnectible(sHost, iPings, iTO)
' Returns True or False based on the output from ping.exe
' Works an "all" WSH versions
' sHost is a hostname or IP
' iPings is number of ping attempts
' iTO is timeout in milliseconds
' if values are set to "", then defaults below used
Dim nRes
If iPings = "" Then iPings = 1 ' default number of pings
If iTO = "" Then iTO = 550 ' default timeout per ping
With CreateObject("WScript.Shell")
nRes = .Run("%comspec% /c ping.exe -n " & iPings & " -w " & iTO _
& " " & sHost & " | find ""TTL="" > nul 2>&1", 0, True)
End With
IsConnectible = (nRes = 0)
End Function
I take a project and export selected tasks into a Gantt chart in Excel.
The tasks that end up in the Excel chart are selected by highlighting them in Project and then running the macro. I would like for the macro to select these tasks by looking at the first and last task of that group. What I mean is I'd like to read the task names, find Task Name "A" and then process all the tasks afterwards until it hits Task Name "Z".
I tried to use the Task ID to set the ID numbers but the task number will change whenever new tasks are added to the project. I also tried using the unique ID but that won't work since there are some tasks between A and Z that have been in the project for a while so setting a specific range for that wouldn't work either.
I feel there is a simple way to do this but I just haven't stumbled upon it yet.
EDIT: Added the code below. The relevant section is just below the comment "Fill cells with Task information".
Sub ExportToExcel()
Dim xlApp As Excel.Application
Dim xlBook As Excel.Workbook
Dim xlSheet As Excel.Worksheet
Dim proj As Project
Dim t As Task
Dim pj As Project
Dim pjDuration As Integer
Dim i As Integer
Dim k As Integer
Dim c As Range
Set pj = ActiveProject
Set xlApp = New Excel.Application
'AppActivate "Excel"
xlApp.Visible = False
Set xlBook = xlApp.Workbooks.Open("C:\Users\Controls\Desktop\ServiceSchedule.xlsx")
xlApp.WindowState = xlMaximized
'Set up Project Detail Headers
Set xlSheet = xlBook.Worksheets(1)
xlSheet.Application.ScreenUpdating = False
xlSheet.Application.DisplayAlerts = False
xlSheet.UsedRange.Delete
xlSheet.Cells.Clear
xlSheet.Cells.ClearContents
'xlSheet.Cells(1, 1).Value = "Project Name"
'xlSheet.Cells(1, 2).Value = pj.Name
'xlSheet.Cells(2, 1).Value = "Project Title"
'xlSheet.Cells(2, 2).Value = pj.Title
'xlSheet.Cells(1, 4).Value = "Project Start"
'xlSheet.Cells(1, 5).Value = pj.ProjectStart
'xlSheet.Cells(2, 4).Value = "Project Finish"
'xlSheet.Cells(2, 5).Value = pj.ProjectFinish
'Set Gantt Chart Timespan
'xlSheet.Cells(1, 7).Value = "Project Duration"
pjDuration = 90
'xlSheet.Cells(1, 8).Value = pjDuration & "d"
'Set up Headers
xlSheet.Cells(4, 1).Value = "Task ID"
xlSheet.Cells(4, 2).Value = "Task Name"
xlSheet.Cells(4, 3).Value = "Name"
xlSheet.Cells(4, 4).Value = "Task Start"
xlSheet.Cells(4, 5).Value = "Task Finish"
xlSheet.Cells(4, 1).Font.Bold = True
xlSheet.Cells(4, 2).Font.Bold = True
xlSheet.Cells(4, 3).Font.Bold = True
xlSheet.Cells(4, 4).Font.Bold = True
xlSheet.Cells(4, 5).Font.Bold = True
'Freeze Rows & Columns
xlSheet.Range("F5").Select
xlSheet.Application.ActiveWindow.FreezePanes = True
'AutoFit Header columns and Hide blank rows
xlSheet.Columns("A:E").AutoFit
xlSheet.Columns("A").Hidden = True
xlSheet.Rows("1:2").Hidden = True
' Add day of the week headers for the entire Project's duration
For i = 0 To pjDuration
'If Today's Date is Sunday
If xlSheet.Application.WorksheetFunction.Weekday(Now()) = 1 Then
xlSheet.Cells(3, i + 6).Value = Now() + i
xlSheet.Cells(3, i + 6).NumberFormat = "[$-409]mmmm d, yyyy;#"
xlSheet.Cells(4, i + 6).Value = Now() + i
xlSheet.Cells(4, i + 6).NumberFormat = "ddd"
End If
'If Today's Date is Monday
If xlSheet.Application.WorksheetFunction.Weekday(Now()) = 2 Then
xlSheet.Cells(3, i + 6).Value = (Now() - 1) + i
xlSheet.Cells(3, i + 6).NumberFormat = "[$-409]mmmm d, yyyy;#"
xlSheet.Cells(4, i + 6).Value = (Now() - 1) + i
xlSheet.Cells(4, i + 6).NumberFormat = "ddd"
End If
'If Today's Date is Tuesday
If xlSheet.Application.WorksheetFunction.Weekday(Now()) = 3 Then
xlSheet.Cells(3, i + 6).Value = (Now() - 2) + i
xlSheet.Cells(3, i + 6).NumberFormat = "[$-409]mmmm d, yyyy;#"
xlSheet.Cells(4, i + 6).Value = (Now() - 2) + i
xlSheet.Cells(4, i + 6).NumberFormat = "ddd"
End If
'If Today's Date is Wednesday
If xlSheet.Application.WorksheetFunction.Weekday(Now()) = 4 Then
xlSheet.Cells(3, i + 6).Value = (Now() - 3) + i
xlSheet.Cells(3, i + 6).NumberFormat = "[$-409]mmmm d, yyyy;#"
xlSheet.Cells(4, i + 6).Value = (Now() - 3) + i
xlSheet.Cells(4, i + 6).NumberFormat = "ddd"
End If
'If Today's Date is Thursday
If xlSheet.Application.WorksheetFunction.Weekday(Now()) = 5 Then
xlSheet.Cells(3, i + 6).Value = (Now() - 4) + i
xlSheet.Cells(3, i + 6).NumberFormat = "[$-409]mmmm d, yyyy;#"
xlSheet.Cells(4, i + 6).Value = (Now() - 4) + i
xlSheet.Cells(4, i + 6).NumberFormat = "ddd"
End If
'If Today's Date is Friday
If xlSheet.Application.WorksheetFunction.Weekday(Now()) = 6 Then
xlSheet.Cells(3, i + 6).Value = (Now() - 5) + i
xlSheet.Cells(3, i + 6).NumberFormat = "[$-409]mmmm d, yyyy;#"
xlSheet.Cells(4, i + 6).Value = (Now() - 5) + i
xlSheet.Cells(4, i + 6).NumberFormat = "ddd"
End If
'If Today's Date is Saturday
If xlSheet.Application.WorksheetFunction.Weekday(Now()) = 7 Then
xlSheet.Cells(3, i + 6).Value = (Now() - 6) + i
xlSheet.Cells(3, i + 6).NumberFormat = "[$-409]mmmm d, yyyy;#"
xlSheet.Cells(4, i + 6).Value = (Now() - 6) + i
xlSheet.Cells(4, i + 6).NumberFormat = "ddd"
End If
'Color Weekend columns
xlSheet.Cells(4, i + 6).ColumnWidth = 10
If xlSheet.Application.Cells(4, i + 6).Text = "Sat" Then
For k = 1 To 100
xlSheet.Cells(4 + k, i + 6).Interior.ColorIndex = 15
Next
End If
If xlSheet.Application.Cells(4, i + 6).Text = "Sun" Then
For k = 1 To 100
xlSheet.Cells(4 + k, i + 6).Interior.ColorIndex = 15
Next
End If
Next
'Merge date cells
For i = 0 To pjDuration Step 7
xlSheet.Cells(3, i + 6).Select
xlSheet.Application.ActiveCell.Resize(1, 7).Select
With xlSheet.Application.Selection
.HorizontalAlignment = xlCenter
.VerticalAlignment = xlBottom
.WrapText = False
.Orientation = 0
.AddIndent = False
.IndentLevel = 0
.ShrinkToFit = False
.ReadingOrder = xlContext
.MergeCells = False
End With
xlSheet.Application.Selection.Merge
Next i
'Fill cells with Task information
Dim SearchString1 As String
Dim SearchString2 As String
SearchString1 = "Buyoffs/Service"
SearchString2 = "History"
**For Each t In ActiveSelection.Tasks
xlSheet.Cells(t.ID + 4, 1).Value = t.ID
xlSheet.Cells(t.ID + 4, 2).Value = t.Name
xlSheet.Cells(t.ID + 4, 3).Value = t.ResourceNames
xlSheet.Cells(t.ID + 4, 4).Value = t.Start
xlSheet.Cells(t.ID + 4, 4).NumberFormat = "[$-409]mm-dd-yy;#"
xlSheet.Cells(t.ID + 4, 5).Value = t.Finish
xlSheet.Cells(t.ID + 4, 5).NumberFormat = "[$-409]mm-dd-yy;#"**
'Loop to color cells to mimic Gantt chart
For i = 5 To pjDuration + 5
If t.Start <= xlSheet.Cells(4, i + 1) And t.Finish >= xlSheet.Cells(4, i + 1) Then
xlSheet.Cells(t.ID + 4, i + 1).Interior.ColorIndex = 37
With xlSheet.Cells(t.ID + 4, i + 1).Borders(xlEdgeBottom)
.LineStyle = xlContinuous
.ThemeColor = 1
.TintAndShade = 0
.Weight = xlThin
End With
End If
Next i
Next t
'Loop To Change Day Headers to Single Char Format
For i = 0 To pjDuration
With xlSheet.Cells(4, i + 6)
If .Text = "Sun" Then
.Value = "S"
ElseIf .Text = "Mon" Then
.Value = "M"
ElseIf .Text = "Tue" Then
.Value = "T"
ElseIf .Text = "Wed" Then
.Value = "W"
ElseIf .Text = "Thu" Then
.Value = "R"
ElseIf .Text = "Fri" Then
.Value = "F"
ElseIf .Text = "Sat" Then
.Value = "S"
End If
End With
xlSheet.Cells(4, i + 6).ColumnWidth = 1.5
Next
'Remove empty rows
xlSheet.Range("A5:A10000").AutoFilter 1, "<>", , , False
'Autofit Columns
xlSheet.Columns("B:E").AutoFit
xlSheet.Columns("B:B").Select
With xlSheet.Application.Selection
.HorizontalAlignment = xlGeneral
.VerticalAlignment = xlBottom
.WrapText = True
.Orientation = 0
.AddIndent = False
.IndentLevel = 0
.ShrinkToFit = False
.ReadingOrder = xlContext
.MergeCells = False
End With
xlSheet.Application.Selection.ColumnWidth = 50
With xlSheet.Application.Selection
.HorizontalAlignment = xlGeneral
.VerticalAlignment = xlBottom
.WrapText = True
.Orientation = 0
.AddIndent = False
.IndentLevel = 0
.ShrinkToFit = False
.ReadingOrder = xlContext
.MergeCells = False
End With
'Format Cells with Borders
xlSheet.Rows("4:4").Select
xlSheet.Application.Selection.Borders(xlDiagonalDown).LineStyle = xlNone
xlSheet.Application.Selection.Borders(xlDiagonalUp).LineStyle = xlNone
xlSheet.Application.Selection.Borders(xlEdgeLeft).LineStyle = xlNone
xlSheet.Application.Selection.Borders(xlEdgeTop).LineStyle = xlNone
With xlSheet.Application.Selection.Borders(xlEdgeBottom)
.LineStyle = xlContinuous
.ColorIndex = xlAutomatic
.TintAndShade = 0
.Weight = xlMedium
End With
xlSheet.Application.Selection.Borders(xlEdgeRight).LineStyle = xlNone
xlSheet.Application.Selection.Borders(xlInsideVertical).LineStyle = xlNone
xlSheet.Application.Selection.Borders(xlInsideHorizontal).LineStyle = xlNone
xlSheet.Columns("E:E").Select
xlSheet.Application.Selection.Borders(xlDiagonalDown).LineStyle = xlNone
xlSheet.Application.Selection.Borders(xlDiagonalUp).LineStyle = xlNone
xlSheet.Application.Selection.Borders(xlEdgeLeft).LineStyle = xlNone
xlSheet.Application.Selection.Borders(xlEdgeTop).LineStyle = xlNone
xlSheet.Application.Selection.Borders(xlEdgeBottom).LineStyle = xlNone
With xlSheet.Application.Selection.Borders(xlEdgeRight)
.LineStyle = xlContinuous
.ColorIndex = xlAutomatic
.TintAndShade = 0
.Weight = xlMedium
End With
xlSheet.Application.Selection.Borders(xlInsideVertical).LineStyle = xlNone
xlSheet.Range("F4:CR4").Select
With xlSheet.Application.Selection
.HorizontalAlignment = xlCenter
.VerticalAlignment = xlBottom
.WrapText = False
.Orientation = 0
.AddIndent = False
.IndentLevel = 0
.ShrinkToFit = False
.ReadingOrder = xlContext
.MergeCells = False
End With
xlSheet.Application.Selection.Borders(xlDiagonalDown).LineStyle = xlNone
xlSheet.Application.Selection.Borders(xlDiagonalUp).LineStyle = xlNone
With xlSheet.Application.Selection.Borders(xlEdgeLeft)
.LineStyle = xlContinuous
.ColorIndex = xlAutomatic
.TintAndShade = 0
.Weight = xlMedium
End With
xlSheet.Application.Selection.Borders(xlEdgeTop).LineStyle = xlNone
With xlSheet.Application.Selection.Borders(xlEdgeBottom)
.LineStyle = xlContinuous
.ColorIndex = xlAutomatic
.TintAndShade = 0
.Weight = xlMedium
End With
With xlSheet.Application.Selection.Borders(xlEdgeRight)
.LineStyle = xlContinuous
.ColorIndex = xlAutomatic
.TintAndShade = 0
.Weight = xlMedium
End With
With xlSheet.Application.Selection.Borders(xlInsideVertical)
.LineStyle = xlContinuous
.ColorIndex = xlAutomatic
.TintAndShade = 0
.Weight = xlMedium
End With
xlSheet.Application.Selection.Borders(xlInsideHorizontal).LineStyle = xlNone
xlApp.Visible = True
xlBook.Save
xlSheet.Application.DisplayAlerts = True
xlSheet.Application.ScreenUpdating = True
xlSheet.Application.ActiveWindow.Zoom = 100
End Sub
Okay I figured something out. Not the way I initially had in mind but it worked. I used the WBS property of Project to skip any task with outline level "1". So it would start at outline level "2" which contained what I wanted. Ending the loop was easy sine I just needed an If statement to jump out of the loop when it came across that last task name.
For Each t In ActiveProject.Tasks
If t.Name = "History" Then
Exit For
End If
If t.Name = "Vacations" Then
TaskA = t.ID
End If
If t.Name = "Buyoffs/Service" Then
TaskB = t.ID
End If
If t.Name = "Buyoffs/Service" Then GoTo NextIteration
TaskOffset = TaskB - TaskA + 1
If t.Name = "Vacations" Then GoTo NextIteration
If t.Name = "Unscheduled" Then GoTo NextIteration
If InStr(1, t.WBS, "1.") Then GoTo NextIteration
xlSheet.Cells(t.ID + 4 - TaskOffset, 1).Value = t.ID
xlSheet.Cells(t.ID + 4 - TaskOffset, 2).Value = t.Name
xlSheet.Cells(t.ID + 4 - TaskOffset, 3).Value = t.ResourceNames
xlSheet.Cells(t.ID + 4 - TaskOffset, 4).Value = t.Start
xlSheet.Cells(t.ID + 4 - TaskOffset, 4).NumberFormat = "[$-409]mm-dd-yy;#"
xlSheet.Cells(t.ID + 4 - TaskOffset, 5).Value = t.Finish
xlSheet.Cells(t.ID + 4 - TaskOffset, 5).NumberFormat = "[$-409]mm-dd-yy;#"
I am running the following macro to apply conditional formatting on a range of cells. What I want is the macro to be triggered anytime those cell values change. The cell values are not changed manually (i.e. they aren't selected by a user and changed), they change automatically because they contain formulas linked to cells in other spreadsheets.
What is the most efficient of doing this?
Sub TestSub3()
Dim i As Integer, j As Integer
For i = 5 To 27
If i Mod 2 <> 0 Then
For j = 2 To 16
If Cells(i, j) = 0 Then
Cells(i, j).Interior.Color = RGB(146, 208, 80) 'light green fill
Cells(i, j).Font.Color = RGB(0, 176, 80) 'dark green font
ElseIf Cells(2, 1) - Cells(i, 1) > 60 And Cells(i, j) > 0 Then
Cells(i, j).Interior.Color = RGB(255, 0, 0) 'red fill
Cells(i, j).Font.Color = RGB(255, 255, 0) 'yellow font
ElseIf Cells(2, 1) - Cells(i, 1) > 52 And Cells(i, j) > 0 Then
Cells(i, j).Interior.Color = RGB(255, 192, 0) 'orange fill, black font
ElseIf Cells(2, 1) - Cells(i, 1) > 45 And Cells(i, j) > 0 Then
Cells(i, j).Interior.Color = RGB(255, 255, 0) 'yellow fill, black font
End If
Next j
End If
Next i
End Sub
You can use "Private Sub Workbook_SheetCalculate(ByVal Sh As Object)" subroutine to perform change function. Paste the below code in the Microsoft excel object-->sheetname place. Look into the attached picture too
Private Sub Workbook_SheetCalculate(ByVal Sh As Object)
Dim i As Integer, j As Integer
For i = 5 To 27
If i Mod 2 <> 0 Then
For j = 2 To 16
'Debug.Print Cells(i, j)
If Cells(i, j).Value = 0 Then
Cells(i, j).Interior.Color = RGB(146, 208, 80) 'light green fill
Cells(i, j).Font.Color = RGB(0, 176, 80) 'dark green font
ElseIf (Cells(2, 1).Value - Cells(i, 1).Value) > 60 And Cells(i, j).Value > 0 Then
Cells(i, j).Interior.Color = RGB(255, 0, 0) 'red fill
Cells(i, j).Font.Color = RGB(255, 255, 0) 'yellow font
ElseIf (Cells(2, 1).Value - Cells(i, 1).Value) > 52 And Cells(i, j).Value > 0 Then
Cells(i, j).Interior.Color = RGB(255, 192, 0) 'orange fill, black font
ElseIf (Cells(2, 1).Value - Cells(i, 1).Value) > 45 And Cells(i, j).Value > 0 Then
Cells(i, j).Interior.Color = RGB(255, 255, 0) 'yellow fill, black font
End If
Next j
End If
End Sub
You can also look into link for your reference
https://msdn.microsoft.com/en-us/library/office/ff839775.aspx