Python XlsxWriter Protect Worksheet - xlsxwriter

How to protect an excel worksheet by allowing sort autofilter using python xlsxwriter
i tried the following code
wb = xlsxwriter.Workbook('test.xlsx')
ws = wb.add_worksheet('TEST')
ws.protect('abcd#09',{'sort':True,'autofilter':True})
/* Data Written to ws*/
wb.close()

That code works but may not be doing what you expect. When I ran it I got the following that shows the sort and autofilter enabled:
If you want to have them protected then just leave them in the default/false condition.

Related

Excel VBA - Sorting With Protected Row and Column

I'm an average/intermediate VBA developer, mostly able to modify existing code and re-use code for expanding Excel projects.
We ran into a situation where someone recorded some Macro's in Excel 2013 but they won't work in Excel 2003. They HAVE to work in Excel 2003 due to the legacy nature of the machine this sheet will be primary on.
So, I did some research and re-wrote the code for the Macros so it would on 2003. However, of the 4 worksheets in this workbook, it only worked on the first page. It drove me crazy trying to figure out why. Finally noticed that on the other 3 worksheets, the first column and row are PROTECTED. If I unprotect them, the re-written Macros work.
So need a little advice on how to make these re-written macros work with the first row and column protected.
This is a sample of the Macro (there are multiple ones like this with just range differences):
Sub KA24()
' Had to Convert Macro to work with the older version of Excel 2003 in the
shop - BW - 8/31/2017
Dim Ws As Worksheet
Set Ws = Worksheets("24 GA KY")
Application.ScreenUpdating = False
Ws.Range("D2:J9").Sort Key1:=Ws.Range("G2"), Order1:=xlAscending,
Header:=xlNo, OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom,
DataOption1:=xlSortNormal
Application.ScreenUpdating = True
End Sub
You can unprotect the Worksheet for use in your VBA code using the UserInterFaceOnly method. This assumes your sheet is password protected with the password "Something", if not just leave out the password part.
Dim Ws As Worksheet
Set Ws = Worksheets("24 GA KY")
Ws.Protect Password:="Something", UserInterFaceOnly:=True
...

Excel hangs when runs VBA in Module

Excel rookie here. I'm trying a very simple task: copying and pasting cells. The Excel will go into "non responding" once the VBA runs. The code was running at one point, but as I developed more lines, Excel stopped responding. I comment out the rest of the line and only run the lines shown below, Excel still hangs. Any ideas? Thanks!
Also, I'm writing the codes in the module in Excel.
Sub EDRII()
Application.ScreenUpdating = False
Dim EDR As Worksheet, Lookup As Worksheet, FA As Worksheet
Set EDR = Sheets("for edr II")
Set Lookup = Sheets("Lookup")
Set FA = Sheets("FA_Segment_Region")
Sheets(EDR).Activate
Range("B6:X10").Copy Range("B5:X9")
Application.ScreenUpdating = True
End Sub
Excel xlsm
You have defined EDR to be a Worksheet and assigned it to be a reference to the sheet called "for edr II".
When you try to use it later, in the line saying
Sheets(EDR).Activate
you are using EDR in a spot where VBA is expecting a String or an Integer (or Long).
That line should simply say
EDR.Activate
It's also a good idea to avoid Activate and Select whenever possible so, rather than activating the sheet, you could just use
EDR.Range("B6:X10").Copy EDR.Range("B5:X9")
for the Copy statement.
Here's some pointers:
Indent your code so it's easier to follow (minor point in your example)
Fully qualify your references (ThisWorkbook.Worksheets(), EDR.Range(), etc)
Rather than copying and pasting, use .Value
Your code was breaking down because you were trying to activate EDR with Sheets(EDR).Activate which should just be EDR.Activate. Either way, when you take into account the points above you see that you don't need to Activate anything anyway!
Sub EDRII()
Application.ScreenUpdating = False
Dim EDR As Worksheet, Lookup As Worksheet, FA As Worksheet
Set EDR = ThisWorkbook.Worksheets("for edr II")
Set Lookup = ThisWorkbook.Sheets("Lookup")
Set FA = ThisWorkbook.Sheets("FA_Segment_Region")
EDR.Range("B5:X9").Value = EDR.Range("B6:X10").Value
Application.ScreenUpdating = True
End Sub

openpyxl data_only gives only a none answer when storing a variable

So basically what I am trying to do is read in some input variables from an excel workbook and write them into some Output Model cells. Then I save the workbook to try to update the data in the Output Model. Since my Output Model cells are formulas I try to reload the workbook as a read data_only and then grab those cells and store them on a separate sheet. Then I save the workbook one more time.
The problem is the values I try to grab (LS, Sales, TPLH) in the data_only loaded workbook reads out as none instead of the values that I need. I eventually want to make this into a loop to iterate over a bunch of input variables, but I wanted to try it with just one set to begin with.
If anyone knows of a better way to do this or what I am doing wrong please let me know! I appreciate any and all feedback.
Here is my code:
from openpyxl import load_workbook
wb2 = load_workbook("Z:\\PythonFiles\\testexcel.xlsx")
sh2 = wb2.get_sheet_by_name("Output Model")
sh= wb2.get_sheet_by_name('OptimizationData')
ForeCast = sh.cell(row=3, column=2).value
sh2.cell(row=3, column=6).value=ForeCast
wb2.save("Z:\\PythonFiles\\testexcel.xlsx")
wb = load_workbook("Z:\\PythonFiles\\testexcel.xlsx", data_only =True)
sh3 = wb.get_sheet_by_name("Output Model")
sh4 = wb.get_sheet_by_name("OptimizationData")
LS=sh3.cell(row=11, column=3).value
Sales = sh3.cell(row=12, column=3).value
TPLH = sh3.cell(row=13, column=3).value
sh4.cell(row=3, column=7).value=LS
sh4.cell(row=3, column=8).value=Sales
sh4.cell(row=3, column=9).value=TPLH
wb.save("Z:\\PythonFiles\\testexcel.xlsx")
Openpyxl will never calculate the result of a formula. It is entirely dependent upon another application having done that. It also means that such values are stripped from a workbook when it is passed through openpyxl. This happens as soon as you save wb2. If you want to access those values then you need to open wb in data-only mode first.

Excel VBA - Formatting script for automation

So here's what I'm trying to do:
Open file: Pc_Profile
Create new sheet: Sheet1
Copy desired cells from Pc_Profile to Sheet1 (see script below)
Copy entire Sheet1 to new excel file: db.xls
Rename sheet to content of cell A5
Create new sheet for next script run
Basically I'm trying to automate an extraction of a TON of excel files into a single organized file. Each script call should extract to its own sheet so there's no overwritten information.
Here is what I have working so far. It just copies the desired cells to a new sheet within the same file.
' Create Excel object
Set objExcel = CreateObject("Excel.Application")
' Open the workbook
Set objWorkbook = objExcel.Workbooks.Open _
("\\[directory]\Pc_Profile.xls")
' Set to True or False, whatever you like
objExcel.Visible = True
objWorkbook.Worksheets("Pc_Profile").Range("A5:D5").Copy
objWorkbook.Worksheets("Sheet1").Range("A1").PasteSpecial
objWorkbook.Worksheets("Pc_Profile").Range("A8:B8").Copy
objWorkbook.Worksheets("Sheet1").Range("A2").PasteSpecial
objWorkbook.Worksheets("Pc_Profile").Range("A13:B13").Copy
objWorkbook.Worksheets("Sheet1").Range("A3").PasteSpecial
objWorkbook.Worksheets("Pc_Profile").Range("A15:D17").Copy
objWorkbook.Worksheets("Sheet1").Range("A4").PasteSpecial
objWorkbook.Worksheets("Pc_Profile").Range("A24:E26").Copy
objWorkbook.Worksheets("Sheet1").Range("A7").PasteSpecial
objWorkbook.Worksheets("Pc_Profile").Range("A28:B30").Copy
objWorkbook.Worksheets("Sheet1").Range("A10").PasteSpecial
objWorkbook.Worksheets("Pc_Profile").Range("A43:B43").Copy
objWorkbook.Worksheets("Sheet1").Range("A13").PasteSpecial
objWorkbook.Worksheets("Pc_Profile").Range("A45:B45").Copy
objWorkbook.Worksheets("Sheet1").Range("A14").PasteSpecial
' Activate Sheet2 so you can see it actually pasted the data
objWorkbook.Worksheets("Sheet2").Activate
I would really appreciate the extra push. I'm automating this for a work project and have no experience with VB - I just learned that on the go.
A couple things that are good practice to get into before I get to your actual question:
1) Any macro that you expect to run a long time should have Application.ScreenUpdating = False before any actual work is done in the code, this tells Excel not to bother with changing what's displayed on the screen (big performance booster). Be sure to include an Application.ScreenUpdating = True near the end of your code
2) Similar to #1, you generally want to include Application.Calculation = xlManual to boost performance. If you have large ranges of cells that your macro needs accurate up-to-date values from, it may be easier to leave the calculation automatic, but that doesn't appear to be the case in this instance.
3) You don't need to create a new Excel instance (which is what your first line of code does). You're already in a perfectly good instance of Excel. This also saves you having to close the other instance at the end of the macro (or worse from forgetting to do so and having memory get hogged by Excel processes that aren't really in use)
As to your specific problem, it sounds like you have more workbooks that Pc_profile to copy from, and that you're wanting to create a new "db.xls" with each run of the macro. Based on those assumptions all you need to do is nest your code starting with 'Open the workbook and objWorkbook.Worksheets("Sheet1").Range("A14").PasteSpecial inside a Do While loop. The thing I'm not sure about is how to control the loop. If the list of files is always the same, you should just include a list on a sheet in the workbook that holds the macro and just iterate through that.
The other thing you should do for ease of coding, and to make the loop more effective is declare and use a Worksheet variable and set if for each workbook to the appropriate sheet to pull data from. Ex.
Dim ws as Worksheet
'The Dim is outside your loop, but this would be inside it
Set ws = objWorkbook.Worksheets("whatever_the_sheet's_name_is")
This way you can replace each occurrence of objWorkbook.Worksheets("Pc_Profile"). with ws., easier to type, easier to read, easier to update, and less error prone.
Next, you don't actually have code for moving Sheet1 to a new workbook, or renaming it. To move it (as well as the other Sheet1's yet to be created), you should, before getting to the Do While loop, have the following
Dim target as Workbook
Set target = Application.Workbooks.Add
Then at almost the end of the loop, you need objWorkbook.Worksheets("Sheet1").Move Before:=Target.Sheets(1)
Last, you need to include objWorkbook.Close SaveChanges:=False after you've moved Sheet1 out of the Pc_Profile and renamed it.

Excel 2010 VBA running in all opened files

I have one excel file (*.xlsm) with VBA code on first sheet:
Private Sub Worksheet_Calculate()
ActiveSheet.ChartObjects("Podtlak").Chart.Axes(xlCategory, xlPrimary).MaximumScale = Range("AV79").Value
End Sub
And second excel file with macro that is changing value in cell in first excel (it is automaticaly recalculated) and then copy value of new result from first excel and paste it to second excel file.
Problem is: when macro is going to second excel and paste value, worksheet is recalculated and code from first excel is calling, but it stops with error because in second excel it cant find chart object "Podtlak".
How to set worksheet_calculate() to run only for file whitch one is it written?
Try specifying the workbook:
ThisWorkbook.ActiveSheet.ChartObjects("Podtlak").Chart.Axes(xlCategory, xlPrimary).MaximumScale = Range("AV79").Value
Or specifying the worksheet and workbook:
ThisWorkbook.Worksheets("yourWorksheetName").ChartObjects("Podtlak").Chart.Axes(xlCategory, xlPrimary).MaximumScale = Range("AV79").Value
I like the 2nd option best as you are clearly specifying the worksheet and workbook that this function runs on. Anytime you use ActiveSheet or ActiveWorkbook, you are relying on the fact that your intended worksheet is active when the code runs.