Salesforce lightningでReportダウンロード用 URLを作る
Salesforce lightningから一旦クラシックモードに変換して、レポートを開く
ReportのURLが下記のよな場合、
https://XXXXXXXX.my.salesforce.com/00O1v000007MXu0
末尾に下記のものをつけて
?isdtp=p1&export=1&enc=UTF-8&xf=csv
結果、以下のようになる。
https://XXXXXXXX.my.salesforce.com/00O1v000007MXu0?isdtp=p1&export=1&enc=UTF-8&xf=csv
ブライ語等の影響で、文字がIndentが右に行ってしまったの対処法(Outlook , Word等)
ベブライ語等の影響で、文字がIndentが右に行ってしまったの対処法
少しめんどくさいですが、下記のように対応可能です。
- Outlookなどから、Wordに対象の文章を貼り付ける
- 文章全部を選択(Ctrl+A)
- WordのVisual Basicを立ち上げて、Documentに下記のコードを追加して実行
Sub main() Application.Run "LtRPara" Application.Run "LtRRun" End Sub |
- 文字が左に戻っているはずなので、Outlook等にコピーして戻す。
SalesforceのReportをCSVでPythonから取得する。
下記のモジュールを使用
github.com
Salesforce lightning
isdtp=p1 と言う記載をclassicより足しておかないと動かない。
URLが少し取得が難しかった(理由:複数のURL表記が有ったため)
import requests import codecs from simple_salesforce import Salesforce site_name = 'Siteの名前を記載してください。' report_id= 'レポートのIDを記載してください' password = 'パスワードに置き換えてください。' username = 'ユーザ名を置き換えてください。' security_token = 'セキュリティ トークンを置き換えてください。' filename = r'ファイル名を入れてください。' sf = Salesforce(username=username, password=password, security_token = security_token) with requests.session() as s: d = s.get("https://%s.salesforce.com/%s?isdtp=p1&export=1&enc=UTF-8&xf=csv"%(site_name,report_id), headers=sf.headers, cookies={'sid': sf.session_id}) text = d.text sf.session.close() fp = codecs.open(filename,'w+','utf8') fp.write(text) fp.close()
Salesforce classic
isdtp=p1 と言う記載をlightningより削除。
import requests import codecs from simple_salesforce import Salesforce site_name = 'Siteの名前を記載してください。' report_id= 'レポートのIDを記載してください'。 password = 'パスワードに置き換えてください。' username = 'ユーザ名を置き換えてください。' security_token = 'セキュリティ トークンを置き換えてください。' filename = r'ファイル名を入れてください。' sf = Salesforce(username=username, password=password, security_token = security_token) with requests.session() as s: d = s.get("https://%s.salesforce.com/%s?export=1&enc=UTF-8&xf=csv"%(site_name,report_id), headers=sf.headers, cookies={'sid': sf.session_id}) text = d.text sf.session.close() fp = codecs.open(filename,'w+','utf8') fp.write(text) fp.close()
PANDAS 特定カラムにある同じ値のカウントを、現在の表に追加する方法
遅い方法、私のテストデータでは1分かかった
def get_count(x): target_column_name = 'Serial Number' return len(df[df[target_column_name]==x[target_column_name]].index) df['count'] = df.apply(get_count,axis=1) df
早い方法
私のテストデータでは1秒もかからなかった
target_column_name = 'Serial Number' df_temp = df.reset_index().groupby(target_column_name).count().reset_index()[[target_column_name,'index']] df_merge = pd.merge(left=df,left_on=target_column_name,right=df_temp,right_on=target_column_name,how='left') df_merge
Pandas column名 操作
- カラム名にヘッダーをつける
df.columns = ['HEADER '+x for x in list(df.columns)]
wxPython RichTextCtrlから画像を取り出す方法
xmlファイルに吐き出して中の画像を取り出しました。
とりあえず私の環境ではpngだった。
imagetype以外は別の処理が必要そうだ。
Imageファイルのヘッダー文字から画像ファイルの種類判定しても良いかもしれない。
# -*- coding: utf-8 -*- ########################################################################### ## Python code generated with wxFormBuilder (version Oct 26 2018) ## http://www.wxformbuilder.org/ ## ## PLEASE DO *NOT* EDIT THIS FILE! ########################################################################### import wx import wx.xrc import wx.richtext # for conv_xml2file import os import codecs import binascii import hashlib import xml.etree.ElementTree as ET try: from StringIO import StringIO except ImportError: from io import StringIO ########################################################################### ## conv_xml2py ########################################################################### def conv_xml2py(xmlpath): base_dir ,ext = os.path.splitext(xmlpath) if not os.path.exists(base_dir): os.mkdir(base_dir) tree = ET.ElementTree(file=xmlpath) md5dat = hashlib.md5() line = 0 img_num = 0 data = '' for item in tree.iter(): item_type = item.tag.split('}')[1] text = item.text if text is None : text = '' text = text.strip() if item_type == 'paragraph' : line += 1 if line != 1: data += '\n' elif item_type == 'text' : data += text elif item_type == 'data' : img_num += 1 img_bin = binascii.unhexlify(text) md5dat.update(img_bin) filename = 'img-%06d-%s.png'%(img_num,md5dat.digest().hex()) img_num += 1 filepath = os.path.join(base_dir,filename) fp = open(filepath,'wb+') fp.write( img_bin ) fp.close() data += '"%s"'%(filename) filepath_py = os.path.join(base_dir,'aaaa.txt') fp_py = codecs.open(filepath_py,'w+','utf8') fp_py.write(data) fp_py.close() ########################################################################### ## Class MyFrame1 ########################################################################### class MyFrame1 ( wx.Frame ): def __init__( self, parent ): wx.Frame.__init__ ( \ self, parent, id = wx.ID_ANY, title = wx.EmptyString, \ pos = wx.DefaultPosition, size = wx.Size( 500,300 ), \ style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL ) self.SetSizeHints( wx.DefaultSize, wx.DefaultSize ) bSizer6 = wx.BoxSizer( wx.VERTICAL ) self.m_button1 = wx.Button( \ self, wx.ID_ANY, u"MyButton", \ wx.DefaultPosition, wx.DefaultSize, 0 ) bSizer6.Add( self.m_button1, 0, wx.ALL, 5 ) self.m_richText1 = wx.richtext.RichTextCtrl( \ self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, \ wx.DefaultSize, \ 0|wx.VSCROLL|wx.HSCROLL|wx.NO_BORDER|wx.WANTS_CHARS ) bSizer6.Add( self.m_richText1, 1, wx.EXPAND |wx.ALL, 5 ) self.SetSizer( bSizer6 ) self.Layout() self.Centre( wx.BOTH ) # Connect Events self.m_button1.Bind( wx.EVT_LEFT_DOWN, self.Click_MyButton ) def __del__( self ): pass # Virtual event handlers, overide them in your derived class def Click_MyButton( self, event ): openFileDialog = wx.FileDialog(None, "Open a file", "", "", "*.xml", wx.FD_SAVE) if openFileDialog.ShowModal() == wx.ID_CANCEL: return project_path = path = openFileDialog.GetPath() handler = wx.richtext.RichTextXMLHandler() rt_buffer = self.m_richText1.GetBuffer() handler.SaveFile(rt_buffer,project_path) conv_xml2py(project_path) app = wx.App(False) #create an object of CalcFrame frame = MyFrame1(None) #show the frame frame.Show(True) #start the applications app.MainLoop()
wxPython RibbonBarの使い方
情報がすごく少ないので、投稿
wxFormBuilder3.9.0から出力されたPythonソースコードには ## PLEASE DO *NOT* EDIT THIS FILE!
とか書いてあるが、残念ながら私の技能ではソース自体修正しないと全くうまく対応出来なかった。
- wxRibbonBarのwxExpandにチェックをつける
横幅がRibbonBarがアイコンの位置までしか表示されない事の対策
- ribbonButtonに適当にIDをつける
- RibbonButtonBarにイベントを追加(なんのイベントでもOK)
self.m_ribbonButtonBarMain.Bind( rb.EVT_RIBBONBUTTONBAR_CLICKED, self.click_ribbon_click )
の様にイベントをrb.EVT_RIBBONBUTTONBAR_CLICKEDにソースレベルで修正
- RibbonButtonBarのイベントハンドラrb.EVT_RIBBONBUTTONBAR_CLICKEDでボタンのIDを取得
ID毎にif文で分岐する。
buttonId = event.GetId()
# -*- coding: utf-8 -*- ########################################################################### ## Python code generated with wxFormBuilder (version Oct 26 2018) ## http://www.wxformbuilder.org/ ## ## PLEASE DO *NOT* EDIT THIS FILE! ########################################################################### import wx import wx.xrc import wx.lib.agw.ribbon as rb ID_RIBBON_NEW = 1000 ID_RIBBON_OPEN = 1001 ID_RIBBON_SAVE = 1002 ID_RIBBON_RUN = 1003 ########################################################################### ## Class TestFrame ########################################################################### class TestFrame ( wx.Frame ): def __init__( self, parent ): wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = u"My Tool", pos = wx.DefaultPosition, size = wx.Size( 601,468 ), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL ) self.SetSizeHints( wx.DefaultSize, wx.DefaultSize ) MainSizer = wx.BoxSizer( wx.VERTICAL ) self.m_ribbonBar = rb.RibbonBar( self , \ wx.ID_ANY, wx.DefaultPosition, wx.Size( -1,-1 ), wx.lib.agw.ribbon.RIBBON_BAR_DEFAULT_STYLE ) self.m_ribbonPageMain = rb.RibbonPage( \ self.m_ribbonBar, wx.ID_ANY, u"Main" , wx.NullBitmap , 0 ) self.m_ribbonBar.SetActivePage( self.m_ribbonPageMain ) self.m_ribbonPanelMain = rb.RibbonPanel( \ self.m_ribbonPageMain, wx.ID_ANY, u"Main" , wx.NullBitmap , wx.DefaultPosition, \ wx.DefaultSize, wx.lib.agw.ribbon.RIBBON_PANEL_DEFAULT_STYLE ) self.m_ribbonButtonBarMain = rb.RibbonButtonBar( \ self.m_ribbonPanelMain, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, 0) self.m_ribbonButtonBarMain.AddSimpleButton( \ ID_RIBBON_NEW, u"New", wx.Bitmap( u"new.png", wx.BITMAP_TYPE_ANY ), wx.EmptyString) self.m_ribbonButtonBarMain.AddSimpleButton( \ ID_RIBBON_OPEN, u"Open", wx.Bitmap( u"open.png", wx.BITMAP_TYPE_ANY ), wx.EmptyString) self.m_ribbonButtonBarMain.AddSimpleButton( \ ID_RIBBON_SAVE, u"Save", wx.Bitmap( u"save.png", wx.BITMAP_TYPE_ANY ), wx.EmptyString) self.m_ribbonButtonBarMain.AddSimpleButton( \ ID_RIBBON_RUN, u"Run", wx.Bitmap( u"run.png", wx.BITMAP_TYPE_ANY ), wx.EmptyString) self.m_ribbonBar.Realize() MainSizer.Add( self.m_ribbonBar, 0, wx.ALL|wx.EXPAND, 5 ) self.SetSizer( MainSizer ) self.Layout() self.m_statusBar2 = self.CreateStatusBar( 1, wx.STB_SIZEGRIP, wx.ID_ANY ) self.Centre( wx.BOTH ) # Connect Events # self.m_ribbonButtonBarMain.Bind( wx.EVT_LEFT_DOWN, self.click_ribbon_click ) self.m_ribbonButtonBarMain.Bind( rb.EVT_RIBBONBUTTONBAR_CLICKED, self.click_ribbon_click ) def __del__( self ): pass # Virtual event handlers, overide them in your derived class def click_ribbon_click( self, event ): buttonId = event.GetId() print('*',buttonId ) if buttonId == ID_RIBBON_NEW : print('new') elif buttonId == ID_RIBBON_OPEN : print('open') elif buttonId == ID_RIBBON_SAVE : print('save') elif buttonId == ID_RIBBON_RUN : print('run') app = wx.App(False) frame = TestFrame(None) frame.Show(True) app.MainLoop()