Skip to content

Commit e01f929

Browse files
2 parents 843d133 + 8ef5533 commit e01f929

File tree

7 files changed

+30
-25
lines changed

7 files changed

+30
-25
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
We are pleased to announce our [one-day Python and Excel workshop](http://www.zoomeranalytics.com/training/) in London on 9th December! Learn how to use ExcelPython, xlwings, spreadgit and the Python Quant Platform directly from the people who developed them.
2+
13
# ExcelPython v2
24

35
Write Excel user-defined functions and macros in Python!

docs/Readme.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,3 @@ If you encounter any issues in getting the add-in set up consult the [troublesho
2222
**Learn how to analyse the problem when something goes wrong**
2323

2424
* [Debugging](tutorials/Debugging01.md)
25-
* [Troubleshooting](tutorials/Troubleshooting01.md)

docs/tutorials/Debugging01.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,11 @@ from xlpython import *
3535

3636
# Add these two lines
3737
import ptvsd
38-
ptvsd.enable_attach(secret='cows')
38+
try:
39+
ptvsd.enable_attach(secret='cows')
40+
except ptvsd.AttachAlreadyEnabledError:
41+
pass
42+
3943

4044
@xlfunc
4145
def DoubleSum(x, y):
@@ -44,6 +48,8 @@ def DoubleSum(x, y):
4448

4549
These to lines enable us to attach the Visual Studio debugger to the Python script, so that we can debug it. Note that the Python process itself must be running for this to work, and ExcelPython does not launch it until it is needed - so just to make sure that it is running and that the `Book1.py` script is loaded, click 'Import Python UDFs'.
4650

51+
(Note: the `try ... except` clause is needed because if `enable_attach` is called twice PTVS will complain that it's already been called. Since we have no way of controlling if it's already been called (for example if the script is reloaded, or if it is called in a different script) we catch the error and ignore it, as recommended in the PTVS documentation.)
52+
4753
At this point you may need to unblock a port on the Windows firewall:
4854

4955
![image](https://cloud.githubusercontent.com/assets/5197585/4387988/f02fbbe8-43e4-11e4-997e-31f12adbdf98.png)

docs/tutorials/Usage01.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
A very simple usage example
22
---
33

4-
You can try out xlpython from the VBA Immediate Window (Ctrl + G if it's not already visible in the VBA window).
4+
You can try out ExcelPython from the VBA Immediate Window (Ctrl + G if it's not already visible in the VBA window).
55

66
Type the following
77

@@ -12,6 +12,8 @@ and press return. You should see
1212
?Py.Str(Py.Eval("1+2"))
1313
3
1414

15+
(It can happen that you get an `Object required` error. This may happen if you do not have your ExcelPython-enabled workbook selected from the VBA project list when you press return in the Immediate Window. This is necessary because otherwise the Immediate Window statement will execute in the wrong VBA context and therefore will not be able to find the `Py` function.)
16+
1517
You can try evaluating any Python expression, and you'll get the result
1618
printed in the Immediate Window.
1719

docs/tutorials/Usage02.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
A more practical use of xlpython
1+
A more practical use of ExcelPython
22
---
33

44
The above example gives a light introduction to manipulating a few simple objects through VBA. In practice though, what's needed is a way to get a load of inputs from Excel, pass them to a method defined in a Python script somewhere, get the outputs back from Python and use them VBA or place them in the spreadsheet as required.
@@ -10,10 +10,10 @@ PyModule returns a pointer to a Python module, much like the import statement. I
1010
?Py.Str(Py.Module("datetime"))
1111
<module 'datetime' (built-in)\>
1212

13-
If you want to call functions from a script which you have placed in a non-standard location, you can tell xlpython to add additional search directories before trying to load the module, as follows:
13+
By default the Python instance associated with a workbook runs in that workbook's folder (as determined by `ThisWorkbook.Path`), so if you place a Python script in that folder, you can load it as a module.
1414

15-
?Py.Str(Py.Module("MyScript", Py.AddPath("D:\Scripts")))
16-
<module 'MyScript' from 'D:\Scripts\MyScript.py'\>
15+
?Py.Str(Py.Module("MyScript"))
16+
<module 'MyScript' from 'C:\WorkbookFolder\MyScript.py'\>
1717

1818
Once you have access to the module you want, you can use `Py.Call` to invoke functions contained in the module (note that `Py.Call` actually calls any method of any object, not just module objects). This is done by explicitly passing the ordered and keyword arguments. For example calling
1919

docs/tutorials/Usage03.md

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,17 @@ def MyFunction(x, y):
1313

1414
The following VBA code can be used to call this function, taking the input parameters from a worksheet and pasting the outputs back to that sheet.
1515

16-
Function PyPath()
17-
PyPath = ThisWorkbook.Path
18-
End Function
19-
20-
Sub CallPythonCode()
21-
Set res = Py.Call( _
22-
Py.Module("MyScript", Py.AddPath(PyPath)), "MyFunction", _
23-
Py.Dict( _
24-
"x", Sheet1.Range("A1").Value2, _
25-
"y", Sheet1.Range("A2").Value2))
26-
Sheet1.Range("A3").Value2 = Py.Var(Py.GetItem(res, "sum"))
27-
Sheet1.Range("A4:B4").Value2 = Py.Var(Py.GetItem(res, "sorted"))
28-
End Sub
29-
30-
The function `PyPath` is a utility function which returns our additional module search path. It's set up so that to access Python scripts we just need to place them in the same folder as the workbook. It's worth defining this once in your workbook's VBA project for use wherever necessary.
16+
```vb.net
17+
Sub CallPythonCode()
18+
Set res = Py.Call( _
19+
Py.Module("MyScript"), "MyFunction", _
20+
Py.Dict( _
21+
"x", Sheet1.Range("A1").Value2, _
22+
"y", Sheet1.Range("A2").Value2))
23+
Sheet1.Range("A3").Value2 = Py.Var(Py.GetItem(res, "sum"))
24+
Sheet1.Range("A4:B4").Value2 = Py.Var(Py.GetItem(res, "sorted"))
25+
End Sub
26+
```
3127

3228
The calls to `Py.Module` and `Py.Call` have been explained above. Once the result dictionary is obtained from the function, its elements can be accessed using `Py.GetItem`.
3329

docs/tutorials/Usage04.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ and all other size ranges have two-dimensional array values.
4040
Since two-dimensional tuples do not exist in Python, it gets converted to a tuple-of-tuples. Often however, you will want to pass a range as a one-dimensional tuple. Consider for example the built-in Python function `sorted`. If you call this function on the range "A1:C1" it returns the same value as is passed in:
4141

4242
```
43-
?Py.Str(Py.Call(Py.Builtins, "sorted", Py.Tuple(Range("A1:C1").Value2)))
43+
?Py.Str(Py.Call(Py.Builtin, "sorted", Py.Tuple(Range("A1:C1").Value2)))
4444
[(3.0, 1.0, 2.0)]
4545
```
4646

@@ -63,7 +63,7 @@ To do this, you can convert the 1x3 two-dimensional VBA array to 3-element one-d
6363
```
6464
?Py.Str(NDims(Range("A1:C1").Value2, 1))
6565
(3.0, 1.0, 2.0)
66-
?Py.Str(Py.Call(Py.Builtins, "sorted", Py.Tuple(NDims(Range("A1:C1").Value2, 1))))
66+
?Py.Str(Py.Call(Py.Builtin, "sorted", Py.Tuple(NDims(Range("A1:C1").Value2, 1))))
6767
[1.0, 2.0, 3.0]
6868
```
6969

@@ -96,7 +96,7 @@ So how do you get the value out of Python and into VBA? The key is to convert it
9696
or in the VBA code by calling the Python conversion function directly on the returned object:
9797

9898
```
99-
?Py.Var(Py.Call(Py.Builtins, "float", Py.Tuple(Py.Eval("norm.cdf(0.0)", locals))))
99+
?Py.Var(Py.Call(Py.Builtin, "float", Py.Tuple(Py.Eval("norm.cdf(0.0)", locals))))
100100
0.5
101101
```
102102

0 commit comments

Comments
 (0)