Python Openpyxl is unable to check from Column 6 onwards - openpyxl

I want to use Openpyxl to check if cells.value='OK' and the interior color of its corresponding row in another sheet is !='FF9BCCFF'. I used the code appended at the end. It works fine for Column 1 to 5 in
R_sht.cell(row = i, column=7).value=='OK'
But when I change to column 6 onwards the code doesn't work. It goes to else block although I have rows that meet the criteria of if block.
I even tested by copying and pasting column 5 to column 6. So both columns have SAME contents/format/etc. And the code works on column 5 but fails in column 6.
I am not sure why there is this issue. I tried on 2 different Excel workbooks. Same issue. Code fails for column 6 onwards.
There is no upload function here for me to show a sample workbook.
But hope someone can still help. Thank you
for i in range (first_used_row,last_used_row+1):
if R_sht.cell(row = i, column=7).value=='OK' and IN_sht.cell(row = i, column=1).fill.start_color.index!='FF9BCCFF':
print(str(i) + "Not Blank")
else:
cell_color=IN_sht.cell(row = i, column=1).fill.start_color.index
print(str(i) + "Blank" + str(cell_color))

Related

VBA - Copy and Paste with increment

Hi i need help on creating a VBA to copy range of cells repeatedly with one column having increments.
Current data
Expected Output
I found a vba but will only copy the rows based on column C without increments on the date
Excel VBA automation - copy row "x" number of times based on cell value
I'm not sure why you would need to do this as excel has built-pattern pattern recognition for these scenarios, after entering two succesive dates if you hover over and click the border of the cell then drag down, the desired date range will appear in the column automatically.
If you still insist on doing this programatically for whatever reason then your question already has multiply feasible solutions here: Add one day to date in cells using VBA
Specify each cell in turn then increment the value by the corresponding row number to return desired date range in column A:
Range("A2").Value = Range("A2").Value + 2 ' add 2 days
Range("A3").Value = Range("A3").Value + 3 ' add 3 days
Range("A4").Value = Range("A4").Value + 4 ' add 4 days
'-------- So on and so forth until desired range is acheived --------'
or alternatively:
Range("A2").value = DateAdd("d", 2, CDate(Range("A2")))
Range("A3").value = DateAdd("d", 3, CDate(Range("A3")))
Speaking as someone who had to learn the hard way, please take my advice and ensure you research your problem thouroughly to find a solution before posting. Refer to the guidelines here if needed.

How to get last column used in excel using vba [duplicate]

This question already has answers here:
Find last used cell in Excel VBA
(14 answers)
Closed 5 years ago.
Hi I am having issues getting to the last column used in my sheet.
I do know that as it stands my last column is 43 and i want it to enter a value at column 44, so then when i search again it will go to column 44 as last column used and then enter a value at 45 and so on and so on. I am using a ref num to find the correct row.
The code I am using is as follows to try get the last column
'find last empty Col in database
LastCol = sou.Cells(2, Columns.count).End(xlToLeft).Column + 1
MsgBox LastCol
'For Loop to cycle through the columns
For x = 2 To LastCol
'If the row value at column 1 = the ref number then continue
If sou.Cells(x, 1).Value = refNum Then
sou.Cells(x, LastCol).Value = Me.commentBox.Text
Exit For
End If
Next
The issue is that for some reason it only goes to column 22. I have tried to use the other ways to get the last column but they have just given me the last column in the whole entire sheet which again is not what I want.
If someone can lend me a hand as I'm a newbie to this it would be greatly appreciated!
To find the last row used, have you tried
lastRow = ActiveSheet.UsedRange.Rows.Count
If that didn't work, please elaborate what went wrong and I can submit more code.

Excel macro generates Subscript out of Range error

All three sheets will have the same column headings in row 1. On the first and second sheets in the workbook (titled "Monthly" and "Annual" respectively), I am using conditional formatting to color cells in columns Y and AC based upon there values as determined by a formula (Yellow if the calculation returns a value less than 90, Red if the value returned is 0 or a negative number). What I would like a macro to do is to copy the entire row from column A through column AD to a third sheet (titled "Maint Due"). It would also be nice if this process were automated so that anytime the values in columns Y and AC changed in the "Monthly" or "Annual" sheets, the information in the "Maint Due" sheet was automatically updated (but if I have to rerun the macro manually for that to happen it's not a big deal).
I've never used the Macro recorder and I can only figure out how to create a macro to copy and paste, so I had no luck there. After doing some more searching and watching some videos I cobbled this together:
Sub Show_on_Maint()
x = 2
'Sets the starting row
Do While Cells(x, 2) <> ""
'Continue to evaluate until a blank cell is reached
If Cells(x, 25) <= 90 Then
'Evaluates the cell in column Y to determine if the value
' is less than or equal to 90
Sheets("Monthly").Rows(x).Copy Sheets("Maint Due").Range("A2")
'Copies the row to the Maint Due sheet
Else
If Cells(x, 29) <= 90 Then
'Evaluates the cell in column AC to determine if the value
' is less than or equal to 90
Sheets("Monthly").Rows(x).Copy Sheets("Maint Due").Range("A2")
'Copies the row to the Maint Due sheet
End If
End If
x = x + 1
Loop
End Sub
When I run/debug it I get a Loop without Do error. I think my logic is sound but I don't have enough experience to figure out why I'm getting that error.
EDIT: Fixed the missing End If before x = x + 1
Now I receive a runtime error 9 "Subscript out of range" at: Sheets("Sheet1").Rows(x).Copy Sheets("Sheet6").Range("A2")
EDIT: Fixed sheet names. Macro now runs without errors but doesn't appear to do anything. Also edited main post for brevity.
You code snippet contains multiple error. The first 'Loop without Do error' has been fixed in comments. The second one, 'Subscript out of range' is self-descriptive, so check the maximum value of x+1 by adding
Debug.Print x = x + 1
to your loop. Also, make sure that you are not referencing a non-existing Worksheet (i.e. Sheets("Sheet6")) in your copy statement.
Hope this will help.

Excel macro for loop?

I am writing a macro in excel and I have a 10 by 10 grid that I need to input a vlookup equation into. So for the first column of data I wrote a for loop
For i = 2 to 11
Cells (i, 30) = "=vlookup (E2" & i & ", B:C, 2, False)"
Next i
And it works the way I want it. Now I would like to write an outer for loop that will allow me to go across the columns.
I started with
For j = 30 to 39
For i = 2 to 11
Cells (i, 30) = "=vlookup (E" & i & ", B:C, 2, False)"
Next i
Next j
But I need E to change to F and I can't figure out how to do that.
I also tried using the Range (Cells(__,__),Cells(__,__)).FormulaR1C1 =...
But I couldn't get that to work either, since it is moving the table as well as fixing E2 across the columns.
If anyone can help I would greatly appreciate it. If not I will just write 10 for loops one for each column.
I think all you need to do is create the first formula and add "$" to appropriately anchor the reference rows/columns at which point you can simply copy the formula across the desired rows/columns.
here is a quick synopsis of anchoring: http://excelonthegrid.wordpress.com/2012/09/26/anchor-with-dollars/
i can give you the final answers if you post the desired formula for
a) column 1 row 1
b) column 1 row 2
c) column 2 row 1
d) column 2 row 2

VBA Macro: Trying to code "if two cells are the same, then nothing, else shift rows down"

My Goal: To get all data about the same subject from multiple reports (already in the same spreadsheet) in the same row.
Rambling Backstory: Every month I get a new datadump Excel spreadsheet with several reports of variable lengths side-by-side (across columns). Most of these reports have overlapping subjects, but not entirely. Fortunately, when they are talking about the same subject, it is noted by a number. This number tag is always the first column at the beginning of each report. However, because of the variable lengths of reports, the same subjects are not in the same rows. The columns with the numbers never shift (report1's numbers are always column A, report2's are always column G, etc) and numbers are always in ascending order.
My Goal Solution: Since the columns with the ascending numbers do not change, I've been trying to write VBA code for a Macro that compares (for example) the number of the active datarow with from column A with Column G. If the number is the same, do nothing, else move all the data in that row (and under it) from columns G:J down a line. Then move on to the next datarow.
I've tried: I've written several "For Each"s and a few loops with DataRow + 1 to and calling what I thought would make the comparisons, but they've all failed miserably. I can't tell if I'm just getting the syntax wrong or its a faulty concept. Also, none of my searches have turned up this problem or even parts of it I can maraud and cobble together. Although that may be more of a reflection of my googling skill :)
Any and all help would be appreciated!
Note: In case it's important, the columns have headers. I've just been using DataRow = Found.Row + 1 to circumvent. Additionally, I'm very new at this and self-taught, so please feel free to explain in great detail
I think I understand your objective and this should work. It doesn't use any of the methodology you were using as reading your explanation I had a good idea how to proceed. If it isn't what you are looking for my apologies.
It starts at a predefined column (see FIRST_ROW constant) and goes row by row comparing the two cells (MAIN_COLUMN & CHILD_COLUMN). If MAIN_COLUMN < CHILD_COLUMN it pushes everything between SHIFT_START & SHIFT_END down one row. It continues until it hits an empty row.
Sub AlignData()
Const FIRST_ROW As Long = 2 ' So you can skip a header row, or multiple rows
Const MAIN_COLUMN As Long = 1 ' this is your primary ID field
Const CHILD_COLUMN As Long = 7 ' this is your alternate ID field (the one we want to push down)
Const SHIFT_START As String = "G" ' the first column to push
Const SHIFT_END As String = "O" ' the last column to push
Dim row As Long
row = FIRST_ROW
Dim xs As Worksheet
Set xs = ActiveSheet
Dim im_done As Boolean
im_done = False
Do Until im_done
If WorksheetFunction.CountA(xs.Rows(row)) = 0 Then
im_done = True
Else
If xs.Cells(row, MAIN_COLUMN).Value < xs.Cells(row, CHILD_COLUMN).Value Then
xs.Range(Cells(row, SHIFT_START), Cells(row, SHIFT_END)).Insert Shift:=xlDown
Debug.Print "Pushed row: " & row & " down!"
End If
row = row + 1
End If
Loop
End Sub
I modified the code to work as a macro. You should be able to create it right from the macro dialog and run it from there also. Just paste the code right in and make sure the Sub and End Sub lines don't get duplicated. It no longer accepts a worksheet name but instead runs against the currently active worksheet.