Running multiple VBA with python - python

I have to perform 200 calculations with an excel spreadsheet, I'm trying to do it through python.
The excel file has 3 macros, and I need to execute each of them every time in order to get all the results.
I manage to run the first macro and get the results, but when I run the second macro, python stops working (like it is in an infinite loop).
I checked the excel file for the same values in my python routine and it works.
This is the code I'm using:
for i in range(0,2):
app = xw.App(visible=False)
# open excel file
wb = app.books.open("original.xlsm")
sheet= wb.sheets['Input-Output']
# get values for case i
soil_type = inputs.soil_type.iloc[i]
cable_diam = round(inputs.diameter.iloc[i],3)
d50 = round(inputs.d50.iloc[i],3)
lin_weight = round(inputs.linear_weight.iloc[i],2)
mu = round(inputs.mu.iloc[i],2)
wd = round(inputs.wd.iloc[i],2)
hs = round(inputs.hs.iloc[i],2)
tp = round(inputs.tp.iloc[i],1)
vs = round(inputs.vs.iloc[i],2)
embed = round(inputs['cable embedment'].iloc[i],3)
# change values
sheet.range('C8').value = C8
sheet.range('C11').value = C11
sheet.range('C15').value = C15
sheet.range('C17').value = C17
sheet.range('C19').value = C19
sheet.range('C20').value = C20
sheet.range('C21').value = C21
sheet.range('C23').value = C23
sheet.range('C29').value = C29
run_macro_1 = wb.app.macro('m1')
run_macro_2 = wb.app.macro('emb.m2')
run_macro_3 = wb.app.macro('m3')
run_macro_1()
run_macro_2()
run_macro_3()
# file name
name = 'omni_'+'case_' + str(i+1) + '.xlsm'
# getting_results
uplift_cond.append(sheet.range('H13').value)
uplift_cond2.append(sheet.range('H15').value)
lat_cond.append(sheet.range('G35').value)
lat_cond2.append(sheet.range('G36').value)
print(i)
# save
wb.save(name)
wb.close()
# close excel and quit
app.quit()
Many thanks for your help

Related

Show excel data in only one Sheet

I'm having some doubts with the following function. I want it to show me the result in a single excel tab but I can't.
def create_df_from_table(c,tab, excelWriter):
list_name = str(c)+"_result_list"
list_name = []
for i,each_row in enumerate(each_tab.rows):
text = (each_cell.text for each_cell in each_row.cells)
if i == -1:
keys = tuple(text)
else:
each_dict_val = tuple(text)
list_name.append(each_dict_val)
list_name_copy = list_name.copy()
result_df = pd.DataFrame(list_name)
print(result_df)
result_df.to_excel(excelWriter, sheet_name=str(c))
return result_df
excelWriter = pd.ExcelWriter('tablasFromDocx1.xlsx')
for c, each_tab in enumerate(file.tables):
globals()[f'result_df_{c}'] = create_df_from_table(c,each_tab, excelWriter)
excelWriter.save()
The code above in line 14 (result_df.to_excel() ) passes the dataframe to excel but in more than one tab and I need only all the data in one

Pivot Table with python win32com

I try to make excel file with Python. For that I use win32com because that seem the best way to make pivot table (pandas is not a good solution), but I have some troubles.
First when I try to make a pivot table on Sheet where there is already a pivot table i have that error message:
Traceback (most recent call last):
File "<ipython-input-55-62ca0c0e21ec>", line 1, in <module>
PivotTable = PivotCache.CreatePivotTable(TableDestination=PivotTargetRange, TableName=PivotTableName, DefaultVersion=win32c.xlPivotTableVersion14)
File "C:\Users\LPLOUV~1\AppData\Local\Temp\gen_py\3.7\00020813-0000-0000-C000-000000000046x0x1x9\PivotCache.py", line 45, in CreatePivotTable
, TableName, ReadData, DefaultVersion)
com_error: (-2147352567, 'Une exception s’est produite.', (0, None, None, None, 0, -2146827284), None)
Second I need to remake some pivot table that exist already, so I need to delete some pivote table from sheet but I don't know how I can make that.
Until there I use this code:
import os
import win32com.client
import time
time_first = time.time()
os.chdir(r'C:\Users\msmith\Desktop')
Excel = win32com.client.gencache.EnsureDispatch('Excel.Application') # Excel = win32com.client.Dispatch('Excel.Application')
win32c = win32com.client.constants
wb = Excel.Workbooks.Open('excel_file.xlsx')
Sheet1 = wb.Worksheets("Sheet1")
Sheet2 = wb.Worksheets("Sheet2")
xldata = Sheet1.UsedRange.Value
data_pivot = xldata[:24291]
cl1 = Sheet1.Cells(1,1)
cl2 = Sheet1.Cells(1+len(data_pivot)-1,1+len(data_pivot[0])-1)
PivotSourceRange = Sheet1.Range(cl1,cl2)
cl3=Sheet2.Cells(200,200)
PivotTargetRange= Sheet2.Range(cl3,cl3)
PivotTableName = 'ReportPivotTable'
PivotCache = wb.PivotCaches().Create(SourceType=win32c.xlDatabase, SourceData=PivotSourceRange, Version=win32c.xlPivotTableVersion14)
PivotTable = PivotCache.CreatePivotTable(TableDestination=PivotTargetRange, TableName=PivotTableName, DefaultVersion=win32c.xlPivotTableVersion14)
PivotTable.PivotFields('A').Orientation = win32c.xlRowField
PivotTable.PivotFields('A').Position = 1
PivotTable.PivotFields('B').Orientation = win32c.xlPageField
PivotTable.PivotFields('B').Position = 1
PivotTable.PivotFields('B').CurrentPage = 'b'
PivotTable.PivotFields('C').Orientation = win32c.xlPageField
PivotTable.PivotFields('C').Position = 2
PivotTable.PivotFields('C').CurrentPage = 5
PivotTable.PivotFields('D').Orientation = win32c.xlPageField
PivotTable.PivotFields('D').Position = 1
PivotTable.PivotFields('D').CurrentPage = 'd'
PivotTable.PivotFields('E').Orientation = win32c.xlPageField
PivotTable.PivotFields('E').Position = 3
PivotTable.PivotFields('E').CurrentPage = "(All)"
PivotTable.PivotFields('D').Orientation = win32c.xlColumnField
PivotTable.PivotFields('D').Position = 1
DataField = PivotTable.AddDataField(PivotTable.PivotFields('F'), Function = win32c.xlSum)
DataField = PivotTable.AddDataField(PivotTable.PivotFields('G'), Function = win32c.xlSum)
wb.SaveAs('excel_file.xlsx')
Excel.Application.Quit()
I think you have a blank field in your data. For example:
This will give you the error.
This will not.

Python program doesn't write to output csv, everything else seems to work correctly

from subprocess import check_output
import csv, operator
extinction_pct = operator.itemgetter('AOT 500','AOT 675','AOT 870','AOT 936','AOT 1020')
with open('csv_export.csv') as f_csv:
reader = csv.DictReader(f_csv)
for row in reader:
with open("INPUT", 'w') as f_in:
f_in.write("&INPUT\n")
f_in.write("WLINF = 0.250\n") #lower frequency value
f_in.write("WLSUP = 4.0\n") #highest frequency value
f_in.write("WLINC = 0.5\n") #wavelength increment
f_in.write("IDAY = 289\n") #computing for a specific day
#f_in.write("ALAT = {Lat}\n".format(**row)) # for Python versions less than 3.6
f_in.write(f"ALAT = {row['Lat']}\n") #latitude of the location
#f_in.write("ALON = {Long}\n".format(**row)) # for Python versions less than 3.6
f_in.write(f"ALON = {row['Long']}\n") #longitude of the location
f_in.write("IDATM = 3\n") #atmopsheric model 2 - mid latitude summer
f_in.write("ISALB = 5\n") #surface albedo feature
f_in.write("IAER = 5\n") #boundary layer aerosol type selection - 5 - user defined spectral dependance of BLA
f_in.write("WLBAER = .500,.675,.870,.936,1.02\n") #wavelenght points for IAER
f_in.write("WBAER = 5*0.9\n") #single scattering albedo
f_in.write("GBAER = 5*0.8\n") #assymetric factor used with IAER
#f_in.write("TIME = {sama]}\n".format(**row)) # for Python versions less than 3.6
f_in.write(f"TIME = {row['sama']}\n") #Time in IST format (-5.30hr)
#f_in.write("QBAER = {}\n".format(','.join(extinction_pct(row))) # for Python versions less than 3.6
f_in.write(f"QBAER = {','.join(extinction_pct(row))}\n") #extinction efficiency percentage
f_in.write("ZOUT = 0.0,15.0\n") #TOA defining
f_in.write("/\n")
check_output('sbdart >> output1.csv',shell=True) #slarrt is the program, and ouytput.csv is the output file
This is my code, with help from #wwii
My last line, check_output csv doesnt write to my output file at all. What could be the issue?
thanks
sbdart is a program, that takes the INPUT file and outputs in the command line
Using method provided here you can try using this.
import subprocess
proc = subprocess.Popen('cmd.exe', stdin = subprocess.PIPE, stdout = subprocess.PIPE)
stdout, stderr = proc.communicate('sbdart >> output.csv')
Make sure you put the full path of sbdart or navigate to the folder having sbdart or add location of sbdart to system path
There are a bunch of other methods in the link provided
Working on Linux with python 3.5
Assume sbdart is executable and we have a file called output1.csv
sbdart looks like this for our test case:
echo $1
echo "$(cat $1)"
output1.csv is as follows:
&INPUT
WLINF = 0.250
WLSUP = 4.0
WLINC = 0.5
IDAY = 289
ALAT = {row['Lat']}
ALON = {row['Long']}
IDATM = 3
ISALB = 5
IAER = 5
WLBAER = .500,.675,.870,.936,1.02
WBAER = 5*0.9
GBAER = 5*0.8
TIME = {row['sama']}
QBAER = {','.join(extinction_pct(row))}
ZOUT = 0.0,15.0
/
>>> import subprocess
>>> subprocess.check_output(['./sbdart output1.csv'],shell=True)
b"output1.csv\n&INPUT\nWLINF = 0.250\nWLSUP = 4.0\nWLINC = 0.5\nIDAY = 289\nALAT = {row['Lat']}\nALON = {row['Long']}\nIDATM = 3\nISALB = 5\nIAER = 5\nWLBAER = .500,.675,.870,.936,1.02\nWBAER = 5*0.9\nGBAER = 5*0.8\nTIME = {row['sama']}\nQBAER = {','.join(extinction_pct(row))}\nZOUT = 0.0,15.0\n/\n"
>>>

How to compress hdf5 file when resizing?

Here is my code:
n = 100000 #This is what makes it tricky - lots of files going into this hdf5 file
with h5py.File('image1.h5','w') as f:
dset_X = f.create_dataset('X',(1,960,224,224),maxshape=(None,960,224,224),chunks=True,compression='gzip')
dset_y = f.create_dataset('y',(1,112,224*224),maxshape=(None,112,224*224),chunks=True,compression='gzip')
n_images = 0
for fl in files[:n]:
X_chunk,y_chunk = get_arrays(fl)
dset_X.resize(n_images+1,axis=0)
dset_y.resize(n_images+1,axis=0)
print dset_X.shape,dset_y.shape
dset_X[n_images:n_images+1,:,:,:]=X_chunk
dset_y[n_images:n_images+1,:,:]=y_chunk
n_images+=1
This works fine and dandy. However, with 1 file, the size of the hdf5 is 6.7MB. With 2 files its 37MB ( should be 12 MB right?). With 10 its all the way up to 388MB (should be 67 right?)
So clearly adding the compression flag to the end of the 2nd and third line isn't working as intended. How can I achieve something like this?
I ended up doing this successfully using pytables.
def get_arrays(each_file):
lab = color.rgb2lab(io.imread(each_file))
X = lab[:,:,:1]
y = lab[:,:,1:]
X_rows,X_columns,X_channels=X.shape
y_rows,y_columns,y_channels=y.shape
X_channels_first = np.transpose(X,(2,0,1))
X_sample = np.expand_dims(X_channels_first,axis=0)
X_3d = np.tile(X_sample,(1,3,1,1))
X_3d_scaled = X_3d * 255.0/X_3d.max()
hc = extract_hypercolumn(model,[3,8,15,22],X_3d_scaled)
hc_scaled = (hc -hc.min())/(hc.max()-hc.min())
print hc_scaled.max(),hc_scaled.min()
hc_expand_dims = np.expand_dims(hc_scaled,axis=0)
y_reshaped = np.reshape(y,(y_rows*y_columns,y_channels))
classed_pixels_first = KNN.predict_proba(y_reshaped)
classed_classes_first = np.transpose(classed_pixels_first,(1,0))
classed_expand_dims = np.expand_dims(classed_classes_first,axis=0)
print "hypercolumn shape: ",hc_expand_dims.shape,"classified output color shape: ",classed_expand_dims.shape
return hc_expand_dims,classed_expand_dims
filters = tables.Filters(complevel=5, complib='zlib')
with tables.openFile('raw.h5','w') as f:
# filters = tables.Filters(complib='blosc', complevel=5)
dset_X = f.create_earray(f.root, 'X', tables.Atom.from_dtype(np.dtype('Float64')), (0,960,224,224),filters=filters)
dset_y = f.create_earray(f.root, 'y', tables.Atom.from_dtype(np.dtype('Float64')), (0,112,224*224),filters=filters)
for fl in files[0:12000]:
X_chunk,y_chunk=get_arrays(fl)
dset_X.append(X_chunk)
dset_y.append(y_chunk)

Running multiple functions based on one imported excel dataframe

I have created multiple functions for each client, They are all basically the same (it only changes the workers names inside of each one of them).
It runs the first functions as it should, but then the second one does not work. It's like the dataframe isn't being carried out throughout the code.
import pandas as pd
import sys
#file loc
R1 = input('Data do Relatório desejado (dd.mm) ---> ')
loc = r'C:\Users\lucas.mascia\Downloads\relatorio-{0}.xlsx'.format(R1)
#opening file with exact needed columns
df = pd.read_excel(loc)
df = df[[2,15,16,17]]
[...]
def func1():
global df, R1, bcsulp1, bcsulp2
#List of solicitantes in Postal Saude
list_sol = [lista_solic["worker1"]]
#filter Postal Saude Solicitantes
df = df[(df['Client']==lista_clientes[2])
& (df['worker'].isin(list_sol))]
#Alphabetical order
df = df.sort_index(by=['worker', 'place'])
#Grouping data of column
gp = df.groupby('worker')
# Loop?
for i in range(1,2):
df = gp.get_group(list_sol[(i-1)])
#Name_i #############################################################
#Protocolo interno e externo --------------------------------------------
p_interno = df[(df['place'].str.contains("C. Martins"))
& (df['task']==lista_tarefas[1])]
globals()['fi'+str(i)] = len(p_interno)
f_i = globals()['fi'+str(i)]
p_externo = df[(~df['place'].str.contains("C. Martins"))
& (df['task']==lista_tarefas[1])]
globals()['fe'+str(i)] = len(p_externo)
f_e = globals()['fe'+str(i)]
#Protocolo Virtual interno e externo ------------------------------------
pv_interno = df[(df['place'].str.contains("C. Martins"))
& (df['task']==lista_tarefas[3])]
globals()['vi'+str(i)] = len(pv_interno)
v_i = globals()['vi'+str(i)]
pv_externo = df[(~df['place'].str.contains("C. Martins"))
& (df['task']==lista_tarefas[3])]
globals()['ve'+str(i)] = len(pv_externo)
v_e = globals()['ve'+str(i)]
#Protocolo postal normal e especial
pp_normal = df[(df['task']==lista_tarefas[51])]
pp_especial = df[(df['task']==lista_tarefas[52])]
globals()['postal'+str(i)] = len(pp_especial) + len(pp_normal)
post = globals()['postal'+str(i)]
#Copia integral e parcial 6,1 - 6,2
copia_i = df[(df['task']==lista_tarefas[61])]
copia_p = df[(df['task']==lista_tarefas[62])]
globals()['copia'+str(i)] = len(copia_p) + len(copia_i)
cop = globals()['copia'+str(i)]
#Copia eletronica
copia_elet = df[(df['task']==lista_tarefas[7])]
globals()['copia_elet'+str(i)] = len(copia_elet)
cop_e = globals()['copia_elet'+str(i)]
#AIJ / Audiencia / Conciliatoria
aij = df[(df['task']==lista_tarefas[81])]
aud = df[(df['task']==lista_tarefas[82])]
conc = df[(df['task']==lista_tarefas[83])]
globals()['audiencia'+str(i)] = len(aij) + len(aud) + len(conc)
audi = globals()['audiencia'+str(i)]
globals()['bcsulp'+str(i)] = [f_i, f_e, v_i, v_e, post, cop, cop_e, audi]
def func2(): [...]
def func3(): [...]
def func4(): [...]
func1()
fucn2()
The following error comes up:
Traceback (most recent call last):
File "Relatorio_Filtro.py", line 736
func2()
File "Relatorio_Filtro.py", line 682
df = gp.get_group(list_sol[(i-1)])
File "C:..."
inds = self._get_index(name)
File "C:..."
return self.indices[name]
KeyError: 'WORKER1'
Question:
Am I missing something so that the excel dataframe imported at the beginnig is carried out throughout the program?

Categories