GeezerVison is showing github.com — Workbook is not passed to macros anymore. · Winand/SimplePython@451349d
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: README.md -3Lines changed: 0 additions & 3 deletions - Display the source diff
- Display the rich diff
| Original file line number | Diff line number | Diff line change |
|---|
| 2 | 2 | Call Python code from Microsoft Office with ease | 3 | 3 |
| 4 | 4 |  | 5 | | - | 6 | | -TODO: | 7 | | -Trying to call another macro while previous one is still running breaks system |
Collapse file Copy file name to clipboardExpand all lines: general.py +3-1Lines changed: 3 additions & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
@@ -47,12 +47,14 @@ def wrapper(doc): | 47 | 47 | if doc_obj: | 48 | 48 | with Context(doc_obj, modules[module]): | 49 | 49 | try: | 50 | | - return func(doc_obj) | | 50 | + return func() | 51 | 51 | except Exception as e: | 52 | 52 | frame = sys.exc_info()[2].tb_next | 53 | 53 | if not frame: frame = sys.exc_info()[2] | 54 | 54 | print("Exception in macro '%s': %s[%s:%d] %s" % | 55 | 55 | (func.__name__, type(e).__name__, module, frame.tb_lineno, e)) | | 56 | + finally: | | 57 | + context.context_app.ScreenUpdating = True #Turn back updating! | 56 | 58 | else: print("Opened document '%s' not found"%doc) | 57 | 59 |
| 58 | 60 | return wrapper | |
Collapse file Copy file name to clipboardExpand all lines: main.py +1Lines changed: 1 addition & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -116,6 +116,7 @@ def __init__(self): | 116 | 116 | self.server = TCPServer((SHARED_SERVER_ADDR, SHARED_SERVER_PORT), Handler) | 117 | 117 | threading.Thread(target=lambda:(pythoncom.CoInitialize(), self.server.serve_forever())).start() | 118 | 118 | self.tray.addMenuItem("Exit", self.btnExit_clicked) | | 119 | + self.terminated.connect(self.btnExit_clicked) | 119 | 120 |
| 120 | 121 | def tray_activated(self, reason): | 121 | 122 | if reason == QtGui.QSystemTrayIcon.Trigger: | |
Collapse file Copy file name to clipboardExpand all lines: simplepython.ui +3Lines changed: 3 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 67 | 67 | </item> | 68 | 68 | <item row="1" column="1"> | 69 | 69 | <widget class="QPushButton" name="btnUpdate"> | | 70 | + <property name="toolTip"> | | 71 | + <string>Update tree of currently available macros</string> | | 72 | + </property> | 70 | 73 | <property name="text"> | 71 | 74 | <string>Update</string> | 72 | 75 | </property> | |
Collapse file Copy file name to clipboardExpand all lines: source/default.py +23-8Lines changed: 23 additions & 8 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 8 | 8 | from context import * | 9 | 9 |
| 10 | 10 | @macro | 11 | | -def unmerge_and_fill(wb): | | 11 | +def unmerge_and_fill(): | 12 | 12 | "разгруппировать все ячейки в Selection и ячейки каждой \ | 13 | 13 | бывшей группы заполнить значениями из их первых ячеек" | 14 | 14 | if TypeName(Selection) != "Range": return | @@ -24,7 +24,7 @@ def fitFactor(ws, hs, wd, hd): | 24 | 24 | return f2 if f2 < f1 else f1 | 25 | 25 |
| 26 | 26 | @macro | 27 | | -def ЭкспортВПрезентацию(wb): | | 27 | +def ЭкспортВПрезентацию(): | 28 | 28 | SLIDE_MARGIN = 8 | 29 | 29 | pp = CreateObject("PowerPoint.Application") | 30 | 30 | pr = pp.Presentations.Add() | @@ -64,21 +64,36 @@ def copy(text=None): | 64 | 64 | win32clipboard.CloseClipboard() | 65 | 65 |
| 66 | 66 | @macro | 67 | | -def я_asrb_format_org(wb): | | 67 | +def я_asrb_format_org(): | 68 | 68 | 'Вспомогательный макрос, форматирует имя организации для добавления в GenerateOrgs' | 69 | 69 | copy(clean(str(ActiveCell.Value))) | 70 | 70 |
| 71 | 71 | @macro | 72 | | -def ttt(wb): | | 72 | +def ttt(): | | 73 | + from context import context_app | | 74 | + context_app.ScreenUpdating=False | 73 | 75 | for i in Selection: | 74 | 76 | x = i.Value | 75 | 77 | if type(x) is str and len(x): | 76 | 78 | ch = x.strip("г. ").split(".") | 77 | 79 | if len(ch)==2: | 78 | | - res = "01.%02s.%s%02s" % (ch[0], "20" if len(ch[1])==2 else "", ch[1]) | | 80 | + res = "1.%s.%s%s" % (ch[0], "20" if len(ch[1])==2 else "", ch[1]) | 79 | 81 | elif len(ch)==3: | 80 | | - res = "%02s.%02s.%s%02s" % (ch[0], ch[1], "20" if len(ch[2])==2 else "", ch[2]) | | 82 | + res = "%s.%s.%s%s" % (ch[0], ch[1], "20" if len(ch[2])==2 else "", ch[2]) | 81 | 83 | else: print(x, ch) | 82 | 84 | i.Value = res | 83 | | - | 84 | | - | | 85 | +@macro | | 86 | +def ttt2(): | | 87 | + from context import context_app | | 88 | + context_app.ScreenUpdating=False | | 89 | + for i in Selection: | | 90 | + x = i.Value | | 91 | + if type(x) is str and len(x): | | 92 | + ch = tuple(x.strip("г. ").split(".")) | | 93 | + if len(ch)==2: | | 94 | + res = "%s.%s.2015"%ch | | 95 | + elif len(ch)==3: | | 96 | + res = "%s.%s.%s%s"%(ch[0], ch[1], "20" if len(ch[2])==2 else "", ch[2]) | | 97 | + else: print(x, ch) | | 98 | + i.Value = res | | 99 | + |
Collapse file Copy file name to clipboardExpand all lines: threaded_ui.py +14-3Lines changed: 14 additions & 3 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 1 | 1 | __author__ = 'МакаровАС' | 2 | 2 |
| 3 | 3 | from PyQt4 import QtCore, QtGui, uic | 4 | | -import sys, queue, pythoncom, types, pathlib | | 4 | +import sys, queue, pythoncom, types, pathlib, win32con, win32gui | 5 | 5 |
| 6 | 6 | DEBUG = False | 7 | 7 | print_def = lambda *args: not DEBUG or print(*args, file=sys.__stdout__) | @@ -134,11 +134,21 @@ def wrap_func(self, *args1, **kwargs1): | 134 | 134 | def module_path(cls): | 135 | 135 | "Get module folder path from class" | 136 | 136 | return pathlib.Path(sys.modules[cls.__module__].__file__).absolute().parent | | 137 | + | | 138 | +class QApplication(QtGui.QApplication): | | 139 | + terminated = QtCore.pyqtSignal() | | 140 | + def winEventFilter(self, message): | | 141 | + if message.message == win32con.WM_DESTROY: | | 142 | + if win32gui.GetClassName(int(message.hwnd) | | 143 | + ).startswith("QEventDispatcherWin32_Internal_Widget"): | | 144 | + self.terminated.emit() | | 145 | + return QtGui.QApplication.winEventFilter(self, message) | 137 | 146 |
| 138 | | -#Events: trayIconActivated | | 147 | +#Widget events are connected to appropriate defs - <widget>_<signal>() | | 148 | +#To catch terminated signal connect it manually | 139 | 149 | def QtApp(Form, *args, flags=QtCore.Qt.WindowType(), ui=None, stdout=None, tray=None, hidden=False, ontop=False, **kwargs): | 140 | 150 | "Create new QApplication and specified window" | 141 | | - app = QtGui.QApplication(sys.argv) | | 151 | + app = QApplication(sys.argv) | 142 | 152 | class Form_(Form): | 143 | 153 | def __init__(self, flags, ui): | 144 | 154 | super(Form, self).__init__(flags=flags|(QtCore.Qt.WindowStaysOnTopHint if ontop else 0)) | @@ -161,6 +171,7 @@ def __init__(self, flags, ui): | 161 | 171 | signal = getattr(widgets[i], m[len(i)+1:], None) | 162 | 172 | if signal: signal.connect(bind(members[m], self)) | 163 | 173 | else: print("Signal '%s' of '%s' not found" % (m[len(i)+1:], i)) | | 174 | + self.terminated = app.terminated | 164 | 175 | if "__init__" in members: | 165 | 176 | super().__init__(*args, **kwargs) | 166 | 177 | form = Form_(flags, ui) | |
|