Select Tasks without ActiveSelection using Project VBA - excel

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;#"

Related

Insert userform data into next column on respective rows

I want to add the values from a form to an Excel sheet.
I have the "headers" in column A from A1 down to A20 with A21 a "score" field that runs from B21 to CZ21 that automatically calculates a score based on the values entered above in each respective column.
A1 through 20 has the headers for the questions and I want the values from the form entered initially in B1 through 20 and then C1-20 and so on and so forth.
As an example, the first form response should be entered into rows B1 to B20 with each row having a value. The second form response will be entered into rows C1 to C20 with each row having it's own value.
Column A is a frozen pane.
Private Sub SaveButton_Click()
'Make Sheet2 active
Sheet4.Activate
'Determine empty Row
emptyRow = WorksheetFunction.CountA(Range("A:A")) + 1
Cells(emptyRow, 2).Value = TextBox1.Value
Cells(emptyRow, 3).Value = Format(Now)
Cells(emptyRow, 4).Value = TextBox3.Value
If CheckBox1.Value = True Then
Cells(emptyRow, 5).Value = CheckBox1
Else
Cells(emptyRow, 5).Value = CheckBox1
End If
If CheckBox2.Value = True Then
Cells(emptyRow, 6).Value = CheckBox2
Else
Cells(emptyRow, 6).Value = CheckBox2
End If
If CheckBox3.Value = True Then
Cells(emptyRow, 7).Value = CheckBox3
Else
Cells(emptyRow, 7).Value = CheckBox3
End If
If CheckBox4.Value = True Then
Cells(emptyRow, 8).Value = CheckBox4
Else
Cells(emptyRow, 8).Value = CheckBox4
End If
If CheckBox9.Value = True Then
Cells(emptyRow, 9).Value = CheckBox9
Else
Cells(emptyRow, 9).Value = CheckBox9
End If
If CheckBox11.Value = True Then
Cells(emptyRow, 10).Value = CheckBox11
Else
Cells(emptyRow, 10).Value = CheckBox11
End If
If CheckBox14.Value = True Then
Cells(emptyRow, 11).Value = CheckBox14
Else
Cells(emptyRow, 11).Value = CheckBox14
End If
If CheckBox16.Value = True Then
Cells(emptyRow, 12).Value = CheckBox16
Else
Cells(emptyRow, 12).Value = CheckBox16
End If
If CheckBox18.Value = True Then
Cells(emptyRow, 13).Value = CheckBox18
Else
Cells(emptyRow, 13).Value = CheckBox18
End If
If CheckBox20.Value = True Then
Cells(emptyRow, 14).Value = CheckBox20
Else
Cells(emptyRow, 14).Value = CheckBox20
End If
If CheckBox22.Value = True Then
Cells(emptyRow, 15).Value = CheckBox22
Else
Cells(emptyRow, 15).Value = CheckBox22
End If
If CheckBox24.Value = True Then
Cells(emptyRow, 16).Value = CheckBox24
Else
Cells(emptyRow, 16).Value = CheckBox24
End If
If CheckBox26.Value = True Then
Cells(emptyRow, 17).Value = CheckBox26
Else
Cells(emptyRow, 17).Value = CheckBox26
End If
If CheckBox27.Value = True Then
Cells(emptyRow, 18).Value = CheckBox27
Else
Cells(emptyRow, 18).Value = CheckBox27
End If
If CheckBox28.Value = True Then
Cells(emptyRow, 19).Value = CheckBox28
Else
Cells(emptyRow, 19).Value = CheckBox28
End If
Cells(emptyRow, 20).Value = TextBox5.Value
Cells(emptyRow, 21).Value = TextBox4.Value
'Clearing data
CheckBox1.Value = "False"
CheckBox2.Value = "False"
CheckBox3.Value = "False"
CheckBox4.Value = "False"
CheckBox9.Value = "False"
CheckBox11.Value = "False"
CheckBox14.Value = "False"
CheckBox16.Value = "False"
CheckBox18.Value = "False"
CheckBox20.Value = "False"
CheckBox22.Value = "False"
CheckBox24.Value = "False"
CheckBox26.Value = "False"
CheckBox27.Value = "False"
CheckBox28.Value = "False"
TextBox1.Value = ""
TextBox3.Value = ""
TextBox4.Value = ""
TextBox5.Value = ""
End Sub
You can do something like this
Private Sub SaveButton_Click()
Dim col as Range
Set col = Sheet4.Range("B1:B20") 'first potential location
'find first unused column
Do While Application.CountA(col) > 0
Set col = col.Offset(0, 1)
Loop
col.cells(1).Value = TextBox1.Value
col.cells(2).Value = Format(Now)
col.cells(3).Value = TextBox3.Value
'etc etc

Incorrect grouping of data in Excel with VBA

I want to group the employees by Emp Code. It works if there is more than 1 record for an employee but if there is < 1 it doesn't work. Like line 13 and 14. This should have been seperate
I have this code:
Dim counter As Integer
Dim customernumber As Integer
counter = 2
customernumber = 2
Do While Worksheets("Mini").Cells(counter, 1).Value <> ""
Worksheets("Mini").Cells(counter, 4).Value = "Testing the Do While"
Worksheets("Mini").Cells(counter, 5).Value = customernumber + 1
If Worksheets("Mini").Cells(counter, 1).Value <> z Then
z = Worksheets("Mini").Cells(counter + 1, 1).Value
With Worksheets("Mini").rows(counter - 1).Borders(xlEdgeBottom)
.LineStyle = xlContinuous
.Weight = xlThick
Worksheets("Mini").Cells(counter, 5).Value = 1
customernumber = 0
End With
End If
How can I change it?
Below is a image of the sheet
You need to set z before the IF test.
Dim counter As Integer
Dim customernumber As Integer
Dim wks As Worksheet
Dim z As Long
Set wks = Worksheets("Mini")
counter = 2
customernumber = 2
With wks
Do While .Cells(counter, 1).Value <> ""
.Cells(counter, 4).Value = "Testing the Do While"
.Cells(counter, 5).Value = customernumber + 1
z = .Cells(counter + 1, 1).Value
If .Cells(counter, 1).Value <> z Then
With .rows(counter - 1).Borders(xlEdgeBottom)
.LineStyle = xlContinuous
.Weight = xlThick
wks.Cells(counter, 5).Value = 1
customernumber = 0
End With
End If
counter = counter + 1
Loop

How to create a stacked chart in VBA with multiple series?

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

VBA Code works for every row except the last one

I have created a VBA code that runs through a .txt (Comma separated) file, does some calculations (Works fine), and then re-organizes the data (Adds some headers and moves all the data down one row, gets rid of irrelevant data, Doesn't work on last row) and spits out a new .csv file. I think it has to do with the fact that I am bumping everything down by one row.
Here is the aforementioned code:
Private Sub Workbook_Open()
Sheets("Sheet1").Cells.ClearContents
Application.Visible = False
'---------------------------------------------------------------------------------------
'Choose and open the .TXT file for conversion
Dim answer As Integer
answer = MsgBox("Do you want to process a .TXT file for use in InfoSWMM?", vbYesNo + vbQuestion, "Select .TXT File")
If answer = vbNo Then
Application.Visible = True
Exit Sub
End If
Dim Ret
Ret = Application.GetOpenFilename("Text Files (*.txt),*.txt")
If Ret <> False Then
With ActiveSheet.QueryTables.Add(Connection:= _
"TEXT;" & Ret, Destination:=Range("$A$1") _
)
.Name = "Sample"
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
TextFilePromptOnRefresh = False
.TextFilePlatform = 437
.TextFileStartRow = 1
.TextFileParseType = xlDelimited
.TextFileTextQualifier = xlTextQualifierDoubleQuote
.TextFileConsecutiveDelimiter = False
.TextFileTabDelimiter = True
.TextFileSemicolonDelimiter = False
.TextFileCommaDelimiter = True
.TextFileSpaceDelimiter = False
.TextFileColumnDataTypes = Array(1, 1, 1, 1, 1, 1)
.TextFileTrailingMinusNumbers = True
.Refresh BackgroundQuery:=False
End With
End If
'---------------------------------------------------------------------------------------
'Do data conversion
Dim CountThem As Integer
Dim CountIt2 As Integer
Dim CountIt As Integer
Dim row As Integer
Dim col As Integer
Dim i As Integer
Dim j As Integer
Dim k As Integer
Dim ant As Double
Dim tester(3) As Double
Dim col_test As Integer
Dim size_test As Integer
Dim rim As Double
Dim Diff2Ele As Double
Dim ResultTxt As String
Dim DiamResultTxt As String
Dim DiamResult As Double
Dim CorrectedDiamResult As Double
Dim Result As Double
Dim MeasDiff As Double
Dim GetElev As Double
Dim GetDiam As String
Dim GetDiam_Val As Double
Dim SVal As Double
Dim Diam2Ft As Double
CountIt = 1
CountIt2 = 1
For row = 1 To ActiveSheet.UsedRange.Rows.Count
If IsEmpty(ActiveSheet.Cells(row, 1).Value) = True Then
Exit For
End If
'Change these values in case feature code library is changed in Carlson, also need to add extra fields
If ActiveSheet.Cells(row, 5).Value = "SD" Or ActiveSheet.Cells(row, 5).Value = "WQ" Or ActiveSheet.Cells(row, 5).Value = "SDCS" Then
col_test = 20
size_test = 19
rim = Val(ActiveSheet.Cells(row, 4).Value) 'Needs val to convert as double
For i = 0 To 3
Result = 0
ResultTxt = Empty
StringLength = Len(Cells(row, col_test))
Str_Length = Len(Cells(row, size_test))
'Gets numbers from string, but ignores 3rd char
DiamResultTxt = Empty
For j = 1 To StringLength
If j = 3 Then GoTo NextIteration 'Skips to next loop on 3rd character, which is an irrelevant number (not one we want)
If IsNumeric(Mid(Cells(row, col_test), j, 1)) = True Or Mid(Cells(row, col_test), j, 1) = "." Then
ResultTxt = ResultTxt & Mid(Cells(row, col_test), j, 1)
End If
NextIteration:
Next j
For j = 1 To Str_Length
If j = 3 Then GoTo nNextIteration 'Skips to next loop on 3rd character, which is an irrelevant number (not one we want)
If IsNumeric(Mid(Cells(row, size_test), j, 1)) = True Then
DiamResultTxt = DiamResultTxt & Mid(Cells(row, size_test), j, 1)
End If
nNextIteration:
Next j
'MsgBox ResultTxt
DiamResult = Val(DiamResultTxt)
CorrectedDiamResult = DiamResult / 12
'MsgBox DiamResult
Result = Val(ResultTxt) 'Needs val to convert as Double
If (InStr(1, ActiveSheet.Cells(row, 34).Value, "TOP") > 0 And InStr(1, ActiveSheet.Cells(row, 34).Value, "PIPE") > 0) Or (InStr(1, ActiveSheet.Cells(row, 36).Value, "TOP") > 0 And InStr(1, ActiveSheet.Cells(row, 36).Value, "PIPE")) Or (InStr(1, ActiveSheet.Cells(row, 38).Value, "TOP") > 0 And InStr(1, ActiveSheet.Cells(row, 38).Value, "PIPE")) Then
tester(i) = Result + CorrectedDiamResult
Else
tester(i) = Result
End If
col_test = col_test + 4
size_test = size_test + 4
Next i
Diff2Ele = WorksheetFunction.Max(tester)
If Diff2Ele = 0 Then
ActiveSheet.Cells(row + 1, 39).Value = "Unable to obtain"
Else
ActiveSheet.Cells(row + 1, 39).Value = rim - Diff2Ele '39 is out of WQ SD and SDCS def. range
End If
End If
'Corrects for top of pipe instances
GetDiam = Empty
If ActiveSheet.Cells(row, 5).Value = "OUTFALL" Then
If InStr(1, ActiveSheet.Cells(row, 18).Value, "TOP") > 0 And InStr(1, ActiveSheet.Cells(row, 18).Value, "PIPE") > 0 Then
GetElev = Val(ActiveSheet.Cells(row, 5).Value)
kLen = Len(Cells(row, 16))
For k = 1 To kLen
If IsNumeric(Mid(Cells(row, 16), k, 1)) = True Or Mid(Cells(row, 16), k, 1) = "." Then
GetDiam = GetDiam & Mid(Cells(row, 16), k, 1)
End If
Next k
GetDiam_Val = Val(GetDiam)
Diam2Ft = GetDiam_Val / 12
ActiveSheet.Cells(row + 1, 39).Value = GetElev - Diam2Ft
Else
ActiveSheet.Cells(row + 1, 39).Value = ActiveSheet.Cells(row, 4).Value
End If
End If
Next row
'---------------------------------------------------------------------------------------
'Prepare sheet re-organization, has to be next step to get altered data from prior process
For row = 1 To ActiveSheet.UsedRange.Rows.Count
If IsEmpty(ActiveSheet.Cells(row, 1).Value) = True Then
Exit For
End If
'ID
ActiveSheet.Cells(row + 1, 44).Value = ActiveSheet.Cells(row, 1).Value
'Description
ActiveSheet.Cells(row + 1, 40).Value = ActiveSheet.Cells(row, 5).Value
'Rim Elevation
If ActiveSheet.Cells(row, 5).Value <> "OUTFALL" Or ActiveSheet.Cells(row, 5).Value <> "DITCH" Then
ActiveSheet.Cells(row + 1, 41).Value = ActiveSheet.Cells(row, 4).Value
End If
'X pos
ActiveSheet.Cells(row + 1, 42).Value = ActiveSheet.Cells(row, 3).Value
'Y pos
ActiveSheet.Cells(row + 1, 43).Value = ActiveSheet.Cells(row, 2).Value
Next row
'---------------------------------------------------------------------------------------
'Re-organize sheet
For row = 1 To ActiveSheet.UsedRange.Rows.Count + 1
If IsEmpty(ActiveSheet.Cells(row, 1).Value) = True Then
If IsEmpty(ActiveSheet.Cells(row, 44).Value) = True Then
Exit For
End If
ElseIf CountIt = 1 Then
ActiveSheet.Cells(row, 1).Value = "ID"
ActiveSheet.Cells(row, 2).Value = "DESC."
ActiveSheet.Cells(row, 3).Value = "RIM ELEV."
ActiveSheet.Cells(row, 4).Value = "YR_INST"
ActiveSheet.Cells(row, 5).Value = "YR_RETIRE"
ActiveSheet.Cells(row, 6).Value = "ZONE"
ActiveSheet.Cells(row, 7).Value = "PHASE"
ActiveSheet.Cells(row, 8).Value = "INV. ELEV."
ActiveSheet.Cells(row, 9).Value = "DEPTH_RIM"
ActiveSheet.Cells(row, 10).Value = "INIT_DPTH"
ActiveSheet.Cells(row, 11).Value = "SURG_DPTH"
ActiveSheet.Cells(row, 12).Value = "POND_AREA"
ActiveSheet.Cells(row, 13).Value = "FLOOD_TYP"
ActiveSheet.Cells(row, 14).Value = "SD_COEFF"
ActiveSheet.Cells(row, 15).Value = "SELECTED"
ActiveSheet.Cells(row, 16).Value = "SYMBOL"
ActiveSheet.Cells(row, 17).Value = "SYMSIZE"
ActiveSheet.Cells(row, 18).Value = "X"
ActiveSheet.Cells(row, 19).Value = "Y"
ActiveSheet.Cells(row, 20).Value = "Z"
ActiveSheet.Cells(row, 21).Value = "SD_MESH"
CountIt = CountIt + 1
Else
ActiveSheet.Cells(row, 1).Value = ActiveSheet.Cells(row, 44).Value
ActiveSheet.Cells(row, 2).Value = ActiveSheet.Cells(row, 40).Value
ActiveSheet.Cells(row, 3).Value = ActiveSheet.Cells(row, 41).Value
ActiveSheet.Cells(row, 4).Value = ""
ActiveSheet.Cells(row, 5).Value = ""
ActiveSheet.Cells(row, 6).Value = ""
ActiveSheet.Cells(row, 7).Value = ""
ActiveSheet.Cells(row, 8).Value = ActiveSheet.Cells(row, 39).Value
ActiveSheet.Cells(row, 9).Value = ""
ActiveSheet.Cells(row, 10).Value = ""
ActiveSheet.Cells(row, 11).Value = ""
ActiveSheet.Cells(row, 12).Value = ""
ActiveSheet.Cells(row, 13).Value = ""
ActiveSheet.Cells(row, 14).Value = ""
ActiveSheet.Cells(row, 15).Value = ""
ActiveSheet.Cells(row, 16).Value = ""
ActiveSheet.Cells(row, 17).Value = ""
ActiveSheet.Cells(row, 18).Value = ActiveSheet.Cells(row, 42).Value
ActiveSheet.Cells(row, 19).Value = ActiveSheet.Cells(row, 43).Value
ActiveSheet.Cells(row, 20).Value = ActiveSheet.Cells(row, 41).Value
ActiveSheet.Cells(row, 21).Value = ""
For CountThem = 22 To 44
ActiveSheet.Cells(row, CountThem).Value = ""
Next CountThem
End If
Next row
'---------------------------------------------------------------------------------------
'Save converted file as .CSV
MsgBox "Choose the desired save location for the .CSV file."
Dim InitialName As String
Dim PathName As Variant
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Sheet1")
InitialName = "sfm_output"
PathName = Application.GetSaveAsFilename(InitialFileName:=InitialName, fileFilter:="CSV (Comma delimited) (*.csv), *.csv")
ws.Copy
ActiveWorkbook.SaveAs Filename:=PathName, _
FileFormat:=xlCSV, CreateBackup:=False
MsgBox "Process completed successfully." & vbNewLine & "File saved to:" & vbNewLine & PathName
'---------------------------------------------------------------------------------------
'Close all Workbooks
Application.DisplayAlerts = False
Application.Quit
End Sub
The section(s) in question are either the "Prepare sheet re-organization" section or the "Re-organize sheet section" (or both). Sorry that the code is sloppy currently, I am just trying to get it to work in the first place before I go through and clean it up.
Any help is greatly appreciated!
Edit: Not sure what happened with the indentation in the code snippet..
Edit2: Here is the GitHub with the .xlsm file and a sample input .txt file.
Thanks for the input data. Please add
'at very top
Option Explicit
'after Dim answer As Integer
Application.Visible = True
Stop
'in data conversion
Dim StringLength As Long, Str_Length As Long, kLen As Long
'please note
'rows 14 & 15 are not SD, WQ, SDCS, but fall thru to OUTFALL,
'but neither are TOP/PIPE because column tested s/b 19 (not 18)
'real problem is in Reorg
If IsEmpty(ActiveSheet.Cells(row, 1).Value) = True Then
If IsEmpty(ActiveSheet.Cells(row, 44).Value) = True Then
Exit For
End If
col-A col-AM etc...
1
2 1641.11 SD 1644.01 4302311.81 216897.65 1
3 1641.63 SD 1644.53 4302261.52 216898 2
4 1648.61 SD 1651.26 4302009.62 216670.98 3
5 1648.99 SD 1652.39 4301918.39 216673.01 4
6 1649.51 SD 1654.41 4301857.91 216626.07 5
7 1651.74 SD 1654.64 4301628.69 216756.85 6
8 1662.07 SD 1665.12 4301234.27 216561.5 7
9 1661.76 SD 1665.02 4301232.65 216482.29 8
10 1661.14 SD 1664.94 4301271.11 216498.17 9
11 1669.14 SD 1669.29 4301040.07 216960.04 10
12 1656.85 SD 1661.1 4302020.09 216349.68 11
13 1658.6 SD 1660.64 4302036.86 216345.72 12
14 Unable..WQ 1656.83 4302020.95 216368.26 13
15 1647 OUTFALL 1647 4302151.24 216561.44 14
1648.76 OUTFALL 1648.76 4302059.74 216518.98 15
Col=1 on row 16 is blank, and ExitFor is done one row too soon.

Object Variable or With Block variable not set Error no 91 and Method 'Range' of object '_Global' failed error no 1004

I have created following programme to run a report using the Excel 2010. However this utility runs without any problem for one time. If i close the report and once again runs the following it gives error at line no 26 showing that the " Object Variable or With block variable not set" and at line no 28 "Method 'Range' of object '_Global' failed". If I close the whole programme and runs once again as new use then it works properly. The basic problem while formatting the excel like Bold, Italics Size of the font etc. Please help me to rectify the problem
Private Sub Command4_Click()
Dim excelApp As excel.Application
Dim excelWB As excel.Workbook
Dim excelWS As excel.Worksheet
Dim rowCounter As Integer
Dim SL As Integer
Dim RL As Integer
RL = 2
Dim list(7) As String
SL = 0
Dim strFileName As String
'On Error Resume Next: Err.Clear
If Text2.Text <> "" Then
Data3.RecordSource = "Select ALLOTDATE,BUDGETCODE,BUDGETSCHEME,DCB_Type,ALLOTSLNO,ALLOTMENT,SchemeFull,year1 from budget where allotment >0 and ALLOTDATE >= #" + Text36.Text + "# and ALLOTDATE <= #" + Text37.Text + "# and budgetcode='" + Text2.Text + "' order by budgetcode "
Data3.Refresh
Set OL = DB.OpenRecordset("Select ALLOTDATE,BUDGETCODE,BUDGETSCHEME,DCB_Type,AllotSlNo,ALLOTMENT,SchemeFull from budget where allotment >0 and ALLOTDATE >= #" + Text36.Text + "# and ALLOTDATE <= #" + Text37.Text + "# and budgetcode='" + Text2.Text + "' order by budgetcode")
End If
If Not Data3.Recordset.EOF Then
Set excelApp = CreateObject("Excel.Application")
excelApp.Visible = True
excelApp.DisplayAlerts = False
Set excelWB = excelApp.Workbooks.Add
Set excelWS = excelWB.Worksheets(1)
excelWS.Name = "Allotment Rcpt"
excelWS.Tab.Color = 220
ActiveWindow.DisplayGridlines = False
excelWS.Cells(1, 1).Value = "Statement Showing the Allotment(Target) Received during the year " + Data3.Recordset.Fields(7) + " under various Budget Heads"
Set A = Range("A1:F1")
A.MergeCells = True
A.HorizontalAlignment = xlCenter
A.VerticalAlignment = xlCenter
With Selection.Font
.Size = 10
.Italic = False
.Bold = True
.Underline = False
.Underline = False
.Name = "Arial Black"
End With
Set A = Nothing
excelWS.Rows(1).RowHeight = 30
excelWS.Rows(2).RowHeight = 30
excelWS.Cells(3, 1).Value = "Sl No"
excelWS.Cells(3, 2).Value = "Date of Receipt "
excelWS.Cells(3, 3).Value = "Allotment Sl No"
excelWS.Cells(3, 4).Value = "Head of Account"
excelWS.Cells(3, 5).Value = "Amount"
excelWS.Cells(3, 6).Value = "Type of Allotment"
excelWS.Range(excelWS.Cells(3, 1), excelWS.Cells(3, 6)).Select
With Selection.Font
.Size = 10
.Italic = False
.Bold = True
.Underline = False
.Name = "Arial Black"
End With
excelWS.Rows(3).RowHeight = 25
Range("A3:F3").Select
With Selection.Borders(xlEdgeLeft)
.LineStyle = xlContinuous
.Weight = xlThin
.ColorIndex = xlAutomatic
End With
With Selection.Borders(xlEdgeTop)
.LineStyle = xlContinuous
.Weight = xlThin
.ColorIndex = xlAutomatic
End With
With Selection.Borders(xlEdgeBottom)
.LineStyle = xlContinuous
.Weight = xlThin
.ColorIndex = xlAutomatic
End With
With Selection.Borders(xlEdgeRight)
.LineStyle = xlContinuous
.Weight = xlThin
.ColorIndex = xlAutomatic
End With
While Not Data3.Recordset.EOF
RL = RL + 1
SL = SL + 1
c = SL + 4
list(1) = SL
list(2) = Format(Data3.Recordset.Fields(0), "DD-MMM-YYYY")
list(3) = Val(Data3.Recordset.Fields(4))
list(4) = Data3.Recordset.Fields(1) + "-" + Data3.Recordset.Fields(2)
list(5) = Data3.Recordset.Fields(5)
list(6) = Left(Data3.Recordset.Fields(3), Len(Data3.Recordset.Fields(3)))
excelWS.Cells(RL + 1, 1).Value = list(1)
excelWS.Cells(RL + 1, 2).Value = list(2)
excelWS.Cells(RL + 1, 3).Value = list(3)
excelWS.Cells(RL + 1, 4).Value = list(4)
excelWS.Cells(RL + 1, 4).Select
With Selection
.WrapText = True
End With
excelWS.Rows(RL + 1).RowHeight = 16
excelWS.Cells(RL + 1, 5).Value = Format(list(5), "#,###.00")
excelWS.Cells(RL + 1, 6).Value = list(6)
'open the file to receive data
Data3.Recordset.MoveNext
Wend
Range("A:F").VerticalAlignment = xlCenter
Range("A:A").HorizontalAlignment = xlCenter
excelWS.Columns("B:C").ColumnWidth = 18
excelWS.Columns("E:F").ColumnWidth = 20
excelWS.Columns("D:D").ColumnWidth = 35
excelWS.Cells(c, 4).Value = "Grand Total"
c = c - 1
c = Format((c), "")
excelWS.Cells(c + 1, 5).Value = "=SUM(E4:E" + c + ")"
c = c + 1
Range("B:B").IndentLevel = 1
Range("E:F").IndentLevel = 1
Range("C:D").IndentLevel = 1
excelWS.Cells(c, 4).Select
With Selection.Font
.Size = 10
.Italic = False
.Bold = True
.Underline = False
.Name = "Arial Black"
End With
Range("A2").HorizontalAlignment = xlLeft
excelWS.Cells(c, 5).Select
With Selection.Font
.Size = 10
.Italic = False
.Bold = True
.Underline = False
.Name = "Arial Black"
End With
Range("A2").HorizontalAlignment = xlLeft
excelWS.Range(excelWS.Cells(c, 1), excelWS.Cells(c, 6)).Select
With Selection.Borders(xlEdgeTop)
.LineStyle = xlContinuous
.Weight = xlThin
.ColorIndex = xlAutomatic
End With
With Selection.Borders(xlEdgeBottom)
.LineStyle = xlContinuous
.Weight = xlThin
.ColorIndex = xlAutomatic
End With
excelWS.Rows(c).RowHeight = 25
excelWS.Columns(1).HorizontalAlignment = xlCenter
excelWS.Columns(2).HorizontalAlignment = xlCenter
excelWS.Columns(3).HorizontalAlignment = xlCenter
excelWS.Columns(4).HorizontalAlignment = xlLeft
excelWS.Columns(5).HorizontalAlignment = xlRight
excelWS.Columns(6).HorizontalAlignment = xlCenter
excelWS.Cells(2, 6).HorizontalAlignment = xlRight
'Save and close
strFileName = (A_DDOSetup.Text1.Text) + "\6_Excel Reports\Target-Rcpt.xlsx"
excelWB.SaveAs FileName:=strFileName, FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
Set excelApp = Nothing
Set excelWB = Nothing
Else
MsgBox "Record not Found"
End If
End Sub
WHILE i RUN THE ABOVE PROGAMME 2ND TIME, I GET AN ERROR IN THE FOLLOWING LINES
i TRIED ADDING OPTION EXPLICIT AND DECLARED OBJECT, STILL PROBLEM CONTINUES
MERGE, FONT SIZE, BOLD LIKE FORMATTING COMMANDS DOES NOT WORK, HOWEVER THE DATA WILL BE DISPLAYED
ActiveWindow.DisplayGridlines = False
excelWS.Cells(1, 1).Value = "Statement Showing the Allotment(Target) Received during the year " + Data3.Recordset.Fields(7) + " under various Budget Heads"
Set A = Range("A1:F1")
A.MergeCells = True
A.HorizontalAlignment = xlCenter
A.VerticalAlignment = xlCenter
With Selection.Font
.Size = 10
.Italic = False
.Bold = True
.Underline = False
.Underline = False
.Name = "Arial Black"
End With
Set A = Nothing
Thank you for Stackoverflow,
I got the problem Solved
.Select and with Selection should be removed and the code to be placed directly to range
**old Code**
excelWS.Cells(c, 4).Select
With Selection.Font
.Size = 10
.Italic = False
.Bold = True
.Underline = False
.Name = "Arial Black"
End With
**Rectified Code**
With excelWS.Cells(c, 4).Font
.Size = 10
.Italic = False
.Bold = True
.Underline = False
.Name = "Arial Black"
End With
sous2817
can't you just post the line that produces the error?
you have a with .selection.font but no where have you performed a valid selection.
try adding RAnge(yourRAnge).select
before
With Selection.Font
.Size = 10
.Italic = False
.Bold = True
.Underline = False
.Underline = False
.Name = "Arial Black"
End With
Set A = Nothing
PS: oh, i strongly recommend you to add "Option Explicit" in your code. at least it will force you to declare variables before using. one more thing, always use Object.property.value

Resources