def safe_plus(x, y): """ Handle "x + y" where x and y could be some combination of ints and strs. """ # Handle Excel Cell objects. Grrr. if excel.is_cell_dict(x): x = x["value"] if excel.is_cell_dict(y): y = y["value"] # Handle NULLs. if (x == "NULL"): x = 0 if (y == "NULL"): y = 0 # Loosely typed languages are terrible. 1 + "3" == 4 while "1" + 3 # = "13". The type of the 1st argument drives the dynamic type # casting (I think) minus variable type information (Dim a as # String:a = 1 + "3" gets "13", we're ignoring that here). Pure # garbage. if (isinstance(x, str)): y = str_convert(y) if (isinstance(x, int)): y = int_convert(y) # Easy case first. if ((isinstance(x, int) or isinstance(x, float)) and (isinstance(y, int) or isinstance(y, float))): return x + y # Fix data types. if (isinstance(y, str)): # NULL string in VB. if (x == 0): x = "" # String concat. return str(x) + y if (isinstance(x, str)): # NULL string in VB. if (y == 0): y = "" # String concat. return x + str(y) # Punt. We are not doing pure numeric addition and # we have already handled string concatentaion. Just # convert things to strings and hope for the best. return str(x) + str(y)
def safe_plus(x, y): """ Handle "x + y" where x and y could be some combination of ints and strs. """ # Handle Excel Cell objects. Grrr. if excel.is_cell_dict(x): x = x["value"] if excel.is_cell_dict(y): y = y["value"] # Handle NULLs. if (x == "NULL"): x = 0 if (y == "NULL"): y = 0 # Easy case first. if ((isinstance(x, int) or isinstance(x, float)) and (isinstance(y, int) or isinstance(y, float))): return x + y # Fix data types. if (isinstance(y, str)): # NULL string in VB. if (x == 0): x = "" # String concat. return str(x) + y if (isinstance(x, str)): # NULL string in VB. if (y == 0): y = "" # String concat. return x + str(y) # Punt. We are not doing pure numeric addition and # we have already handled string concatentaion. Just # convert things to strings and hope for the best. return str(x) + str(y)
def str_convert(arg): """ Convert a VBA expression to an str, handling VBA NULL. """ if (arg == "NULL"): return '' if (excel.is_cell_dict(arg)): arg = arg["value"] try: return str(arg) except Exception as e: if (isinstance(arg, unicode)): return ''.join(filter(lambda x:x in string.printable, arg)) log.error("Cannot convert given argument to str. Defaulting to ''. " + str(e)) return ''
def safe_plus(x, y): """Handle "x + y" where x and y could be some combination of ints and strs. @param x (any) LHS of the addition. @param y (any) RHS of the addition. @return (str, float, or int) The result of x+y based on the types of x and y. """ # Handle Excel Cell objects. Grrr. import excel if excel.is_cell_dict(x): x = x["value"] if excel.is_cell_dict(y): y = y["value"] # Handle NULLs. if (y == "NULL"): y = 0 if (x == "NULL"): # Ugh. If x is uninitialized and we are adding a string to it # it looks like maybe VB makes this whole thing a string? if isinstance(y, str): x = "" else: x = 0 # Loosely typed languages are terrible. 1 + "3" == 4 while "1" + 3 # = "13". The type of the 1st argument drives the dynamic type # casting (I think) minus variable type information (Dim a as # String:a = 1 + "3" gets "13", we're ignoring that here). Pure # garbage. import vba_conversion if (isinstance(x, str)): y = vba_conversion.str_convert(y) if (isinstance(x, int)): y = vba_conversion.int_convert(y) # Easy case first. if (isinstance(x, (float, int)) and isinstance(y, (float, int))): return x + y # Fix data types. if (isinstance(y, str)): # NULL string in VB. if (x == 0): x = "" # String concat. return str(x) + y if (isinstance(x, str)): # NULL string in VB. if (y == 0): y = "" # String concat. return x + str(y) # Punt. We are not doing pure numeric addition and # we have already handled string concatentaion. Just # convert things to strings and hope for the best. return str(x) + str(y)