Using Excel named ranges in Python with openpyxl - python

How do I loop through the cells in an Excel named range/defined name and set each cell value within the named range using openpyxl with Python 2.7?
I found the following, but have not managed to get it to work for printing and setting the values of individual cells within the named range.
Read values from named ranges with openpyxl
Here's my code so far, I have put in comments where I am looking to make the changes. Thanks in anticipation.
#accessing a named range called 'metrics'
namedRange = loadedIndividualFile.defined_names['metrics']
#obtaining a generator of (worksheet title, cell range) tuples
generator = namedRange.destinations
#looping through the generator and getting worksheet title, cell range
cells = []
for worksheetTitle, cellRange in generator:
individualWorksheet = loadedIndividualFile[worksheetTitle]
#==============================
#How do I set cell values here?
# I am looking to print and change each cell value within the defined name range
#==============================
print cellRange
print worksheetTitle
#theWorksheet = workbook[worksheetTitle]
#cell = theWorksheet[cellRange]

I managed to resolve it. Perhaps the following will be useful to someone else who is looking to access the values of each cell in a defined name or named range using openpyxl.
import openpyxl
wb = openpyxl.load_workbook('filename.xlsx')
#getting the address
address = list(wb.defined_names['metrics'].destinations)
#removing the $ from the address
for sheetname, cellAddress in address:
cellAddress = cellAddress.replace('$','')
#looping through each cell address, extracting it from the tuple and printing it out
worksheet = wb[sheetname]
for i in range(0,len(worksheet[cellAddress])):
for item in worksheet[cellAddress][i]:
print item.value`

Related

How can I find the last non-empty row of excel using openpyxl 3.03?

How can I find the number of the last non-empty row of an whole xlsx sheet using python and openpyxl?
The file can have empty rows between the cells and the empty rows at the end could have had content that has been deleted. Furthermore I don't want to give a specific column, rather check the whole table.
For example the last non-empty row in the picture is row 13.
I know the subject has been extensively discussed but I haven't found an exact solution on the internet.
# Open file with openpyxl
to_be = load_workbook(FILENAME_xlsx)
s = to_be.active
last_empty_row = len(list(s.rows))
print(last_empty_row)
## Output: 13
s.rows is a generator and its list contains arrays of each rows cells.
If you are looking for the last non-empty row of an whole xlsx sheet using python and openpyxl.
Try this:
import openpyxl
def last_active_row():
workbook = openpyxl.load_workbook(input_file)
wp = workbook[sheet_name]
last_row = wp.max_row
last_col = wp.max_column
for i in range(last_row):
for j in range(last_col):
if wp.cell(last_row, last_col).value is None:
last_row -= 1
last_col -= 1
else:
print(wp.cell(last_row,last_col).value)
print("The Last active row is: ", (last_row+1)) # +1 for index 0
if __name__ = '___main__':
last_active_row()
This should help.
openpyxl's class Worksheet has the attribute max_rows

Can you delete rows in Python with openpyxl by setting all cell values in a row to 'None'?

I am using openpyxl to attempt to delete rows from a spreadsheet. I understand that there is a funciton specifically for deleting rows, however, I was trying to overcome this problem without knowledge of that function, and I am now wondering why my method does not work.
To simplify the problem, I set up a spreadsheet and filled it with letters in some of the cells. In this case, the first print(sheet.max_row) printed "9". After setting all the cell values to None, I expected the number of rows to be 0, however, the second print statement printed "9" again.
Is it possible to reduce the row count by setting all the cells in a row to None?
import openpyxl
from openpyxl import load_workbook
from openpyxl.utils import get_column_letter, column_index_from_string
spreadsheet = load_workbook(filename = pathToSpreadsheet) #pathToSpreadsheet represents the absolute path I had to the spreadsheet that I created.
sheet = spreadsheet.active
print(sheet.max_row) # Printed "9".
rowCount = sheet.max_row
columnCount = sheet.max_column
finalBoundary = get_column_letter(columnCount) + str(rowCount)
allCellObjects = sheet["A1":finalBoundary]
for rowOfCells in allCellObjects:
for cell in rowOfCells:
cell.value = None
print(sheet.max_row) # Also printed "9".
Thank you for your time and effort!
Short answer NO.
However, you could access the cell from the sheet with the cell coordinates and delete them.
for rowOfCells in allCellObjects:
for cell in rowOfCells:
del sheet[cell.coordinate]
print(sheet.max_row)
A little more elaborate answer would be that a worksheet in Openpyxl stores it's _cells as a dict with coordinates as key. max_row property is defined
#property
def max_row(self):
"""The maximum row index containing data (1-based)
:type: int
"""
max_row = 1
if self._cells:
rows = set(c[0] for c in self._cells)
max_row = max(rows)
return max_row
So if the cells was None, the keys/coordinates would still prevail eg: _cells = {(1,1):None, (1,2):None, (5,4): None}.
max_rowwould then still give us the biggest y-component of the key.

Reading a named range from excel - Python - xlrd

Following is the piece of code that I wrote, and I'm unable to proceed beyond reading the range. I want to be able to read the actual content of the range. Any help is appreciated.
import xlrd
xlBook = xlrd.open_workbook('data.xlsx')
# Open the sheet
sht = xlBook.sheet_by_name('calc')
# Look at the named range
named_obj = xlBook.name_map['load'][0]
# Now, able to retrieve the range
rangeData = (named_obj.formula_text)
(sheetName,ref) = rangeData.split('!')
# Gives me the range as $A$2:$B$20
print(ref)
# How do I print the contents of the cells knowing the range.
My method is to find out his column coordinates,
but I still recommend using openpyxl to be more intuitive.
def col2int(s: str):
weight = 1
n = 0
list_s = list(s)
while list_s:
n += (ord(list_s.pop()) - ord('A')+1) * weight
weight *= 26
return n
# ...
# How do I print the contents of the cells knowing the range. ↓
temp, col_start, row_start, col_end, row_end = ref.replace(':', '').split('$')
for row in range(int(row_start)-1, int(row_end)):
for col in range(col2int(col_start)-1, col2int(col_end)):
print(sht.cell(row, col).value)
the xlrd, xlwt, xlutils are meant for .xls files per their documentation. It recommends openpyxl for .xlsx files. Then you can use this:
Read values from named ranges with openpyxl

Finding Range of active/selected cell in Excel using Python and xlwings

I am trying to write a simple function in Python (with xlwings) that reads a current 'active' cell value in Excel and then writes that cell value to the cell in the next column along from the active cell.
If I specify the cell using an absolute reference, for example range(3, 2), then I everything is ok. However, I can't seem to manage to find the row and column values of whichever cell is selected once the function is run.
I have found a lot of examples where the reference is specified but not where the active cell range can vary depending on the user selection.
I have tried a few ideas. The first option is trying to use the App.selection that I found in the v0.10.0 xlwings documentation but this doesn't seem to return a range reference that can be used - I get an error "Invalid parameter" when trying to retrieve the row from 'cellRange':
def refTest():
import xlwings as xw
wb = xw.Book.caller()
cellRange = xw.App.selection
rowNum = wb.sheets[0].range(cellRange).row
colNum = wb.sheets[0].range(cellRange).column
url = wb.sheets[0].range(rowNum, colNum).value
wb.sheets[0].range(rowNum, colNum + 1).value = url
The second idea was to try to read the row and column directly from the cell selection but this gives me the error "Property object has no attribute 'row'":
def refTest():
import xlwings as xw
wb = xw.Book.caller()
rowNum = xw.App.selection.row
colNum = xw.App.selection.column
url = wb.sheets[0].range(rowNum, colNum).value
wb.sheets[0].range(rowNum, colNum + 1).value = url
Is it possible to pass the range of the active/selected cell from Excel to Python with xlwings? If anyone is able to shed some light on this then I would really appreciate it.
Thanks!
You have to get the app object from the workbook. You'd only use xw.App directly if you wanted to instantiate a new app. Also, selection returns a Range object, so do this:
cellRange = wb.app.selection
rowNum = cellRange.row
colNum = cellRange.column

How to get excel sheet name in Python using xlrd

Please see the code below.
def getSheetName(file_name):
pointSheetObj = []
import xlrd as xl
TeamPointWorkbook = xl.open_workbook(file_name)
pointSheets = TeamPointWorkbook.sheet_names()
for i in pointSheets:
pointSheetObj.append(TeamPointWorkbook.sheet_by_name(i))
I need to get the name of the excel sheet name from the list pointSheetObjby iterating it.
I have modified the code I gave as a question and have got what I needed actually,
def getSheetName(file_name):
pointSheetObj = []
import xlrd as xl
TeamPointWorkbook = xl.open_workbook(file_name)
pointSheets = TeamPointWorkbook.sheet_names()
for i in pointSheets:
pointSheetObj.append(tuple((TeamPointWorkbook.sheet_by_name(i),i)))
so if the list (of tuple) pointSheetObj is iterated we have name of the sheet at index 1 of the tuple inside the pointSheetObj.
By doing this I have got the name and the worksheet object with which I can carry on with other sheet related methods.

Categories

Resources