How to open first sheet and write to the second column using openpyxl? - openpyxl

I'm using an existing excel sheet and the Zillow API to pull the square feet from each house in my neighborhood. I want to open an existing excel workbook, make the first worksheet active, and write the square feet in the second column.
I think the problem is it's not make the worksheet active to write the square feet into the second column. There's quite a bit of code underneath that works when I print to console. I'm trying to use a simple ws.write method but it doesn't recognize ws as a class.
def neighborhood_test():
location = "Address List Cypress Bend.xlsx"
wb_out = Workbook(location)
ws = wb_out.active
print(type(ws))
It should return a worksheet class but returns class 'NoneType' instead.

I figured out what I was doing wrong but now I need to learn how to iterate through it using other xlrd and Zillow API methods. This is the code you need to use an existing excel sheet.
def neighborhood_test():
location = "Address List Cypress Bend.xlsx"
wb_out = load_workbook(location)
worksheet = wb_out.active
print(worksheet.title)
This successfully prints out the first sheet which is Sheet1 for me.

Related

Vlookup data in certain external excel file using a function

I use a lot of Vlookup to find prices in a certain file (c:/pricelist.xlsx), using the product code. I would like to simplify it by creating a new VBA function, but it does not work.
Function findprice(codes)
Dim price
Dim pricebook As Workbook
Dim pricesheet As Worksheet
Dim pricerange As Range
Dim coderange As Range
Set pricebook = Workbooks("c:\info\pricelist.xlsx")
Set pricesheet = pricebook.Sheets("Sheet2")
Set pricerange = pricesheet.Range("FF1:FF20000")
Set coderange = pricesheet.Range("H1:H20000")
findprice = Application.Index(pricerange, Application.Match(codes, coderange, 0))
End Function
I can't say for sure since your question didn't include any sample data or explanation of what/why you're trying to do, but I suspect you're over-complicating this is a few ways.
You don't need a custom function to call a worksheet function from the worksheet. Just use the worksheet functions instead.
In this case VLookup is easier and saves a step (as you suggested in your title.)
Instead of referring to huge ranges of two cells, just refer to the whole columns.
Referring to cells in another Excel file is just like any other formula that refers to another file. (More infor here)
You should be able to use something like this on the worksheet:
=VLOOKUP(A1,'c:\info\pricelist.xlsx'!$H:$FF,155,FALSE)
...where A1 is the value to match (ie., codes).
If you do need this is VBA for some reason, it's easy to adapt just like your sample function.
More Information:
Office Support : Create or change a cell reference
Office Support : Create an external reference (link) to a cell range in another workbook

Take a selection of Excel cells, store each in range to a variable, and print text to a script

I am trying to automate a script that I use for PowerShell. When I get a request, instead of editing the script line by line with required information, I would like to create an Excel spreadsheet, input the data required, and populate my script with those variables in the correct location.
From a high level view with limited programming experience, this does not seem overly complicated but I cannot figure it out.
I am able to do bits and pieces of what I am trying to accomplish, but not everything together. Below is step by step what I want to accomplish.
Input data into Cells B10 through B16
Store each cell into an individual variable
Hit the command button which will take the variables and print/overwrite a file already created.
I have a specific file path that I need to use.
Here is the code that I have already, that I see will copy the cells and open my PowerShell module.
Public Sub CommandButton1_Click()
Dim fileName As Variant
Dim Azure As Workbook
Dim wsSource As Worksheet
Set Azure = ActiveWorkbook
Set wsSource = ActiveSheet
'Copy range on original sheet
wsSource.Range("B10:B16").Copy
fileName = Shell("powershell_ise.exe ""c:\Azure\AZURE_1.ps1""", vbNormalFocus)
End Sub
I can see that the above code doesn't accomplish what I need to do. However, I can see that I can use the button, copy the cells, and open the required file.
What I need to do is take each cell and place at a certain spot in my script and overwrite the previous file.

Shapes not tied to worksheets?

ok so,
I was hoping to have some stuff in my excel app persist, as in hang around, and I want something a little more reliable than global variables as these are reset when code is edited or if say the app is halted. (which does often happen)
So I've been using shapes, and they work good, but they rely on at least one worksheet always being constant right? as shapes are tied to sheets, if the sheet with the shapes gets deleted the shapes go away. And the users often delete / add new sheets, theres no one sheet that is always a constant, and they wouldnt let me force that on them either.
so is there a way to make shapes tied to workbooks instead of sheets? so then if a sheet is deleted with shapes on it, the shapes wont disapear.
any help or other suggestions appeciated
Edit
Thanks again to: #David Zemens for the answer that got me through, just in case anyone ever looks at this down the road, the code to add a named range is: workbook.Names.Add Name:="Name", RefersTo:="value" - you NEED to add refersto or it will error. you can put in a temp value like "temp" and set the value later, but you have to have refers to when you add
You can use Named Ranges to save string data between sessions. They can be children of the Workbook or of specific Worksheets. You will want the former. From the Formula Ribbon, Names Manager, Define Name like so:
Then, in your VBA, you can retrieve and set this range's value like:
Public Const CSVFileName as String = "sFileName"
Sub YourSubroutine()
Dim nm As Name
Set nm = ActiveWorkbook.Names(CSVFileName)
'Get the value:
MsgBox Replace(Replace(nm.Value, "=", vbNullString), """", vbNullString)
'Set the value:
nm.Value = "C:\documents\filename.CSV"
End Sub
The value associated with the Named Range persists beyond runtime, it is basically a property of the workbook.
I will post this now for you to review. I will try to work up an example of the XML Customer Data, and will revise my answer with that, later.

Determine if WorkSheet.Name is NOT in Workbook or String is not in Array VB.NET

This seems like such a simple question, but I can't seem to find a good way to do it. I want to check if the name of an Excel Worksheet with an index of 'n' is not in the original set of worksheet names of my VSTO workbook.
The workbook has 13 worksheets in the template and the program adds more sheets to the end and sometimes the middle. Any sheet added wouldn't be named one of the sheet names included in the template (I've successfully blocked this). I often want to take actions to all the sheets added that are not of the orginal 13, so I had hoped to try and use an array, or the list ThisWorkbook.Names as it exists from the initial template.
Right now my work around is:
If ThisWorkbook.Worksheets(n).Name <> Sheet1.Name OrElse ThisWorkbook.Worksheets(n).Name <> wbX.Sheet2.Name ..... <>wbX.Sheet13.Name
Needless to say this is cumbersome. Am I even thinking about this the right way, or is there an easier way to check if a name is not in the original sheet names?
I know that if I could force all the sheets after 13 I could just use the index, but at the moment that's not feasible for the intention of the project.
At startup fill all worksheetnames from the template into a List:
Dim templateSheets As List(Of String) = new List(Of String)
For Each sheet As Excel.Worksheet in Globals.ThisWorkbook.Worksheets
templateSheets.Add(sheet.Name)
Next
Then your above query can get abbreviated to
If Not templateSheets.Contains(ThisWorkbook.Worksheets(n).Name) Then

Recorded macro does not work on chart object

I recorded the following macro :
Sheets("Rejets Techniques TGC").Select
ActiveSheet.ChartObjects("Graphique 1").Activate
ActiveChart.Axes(xlCategory).Select
ActiveChart.SeriesCollection(1).Values = "='Données'!$EU$68:$IJ$68"
ActiveChart.SeriesCollection(1).XValues = "='Données'!$EU$1:$IJ$1"
However when I try to lauch it I get this error (translated from french):
Execution error '-2147024809 (80070057)'
There is no element with this name
How can this be? if there was no graph named this way I wouldn't have been able
to record it.
(yes I'm running it from the good sheet)
Thanks.
Here's what it comes down to: Your chart is not an object on the sheet, it is the sheet.
So while you use ActiveSheet.ChartObjects("Graphique 1").Activate to start your code, there are no ChartObjects found in your sheet, because the sheet is the Chart. So here's how you get around it:
Dim CO As Variant
Set CO = ActiveSheet
CO.Axes(xlCategory).Select
CO.SeriesCollection(1).Values = "='Données'!$ET$68:$IJ$68"
CO.SeriesCollection(1).XValues = "='Données'!$ET$1:$IJ$1"
And this should work just fine. I noticed that when I looked at the chart tab, I couldn't get into any cells. This is not abnormal, but it is not the most common way (that I see) to create the chart. To verify, I added a watch on the ActiveSheet and saw that it was indeed a chart (of type Object/Graph2) with all the normal chart methods available to it.
From there, I just plugged in your code, converting to the CO variable (but yours should still work using ActiveSheet across the board), and ran with no errors.
As a side note, using ActiveSheet is not always effective, and it is generally better to explicitly call the sheet, i.e. Set CO = ThisWorkbook.Sheets("Rejets Techniques TGC")
1 - Check if the active sheet is the one that contaisn the chart. Or use the sheet name in code to run it from any sheet.
2 - Check if the good sheet contains the chart with exact "Graphique 1" name. Maybe there's an underline, like "Graphique_1", or no space "Graphique1"...