Wednesday, 28 October 2015

Import/ Update Financial dimension through Excel or Table's data

Import/Update Financial dimension through excel data

 
 

 
 
Job: static void importFinancialDimension(Args _args)
{
SysExcelApplication application;

SysExcelWorkbooks workbooks;

SysExcelWorkbook workbook;

SysExcelWorksheets worksheets;

SysExcelWorksheet worksheet;

SysExcelCells cells;

COMVariantType type;

Name name;

FileName filename;

CustAccount custAccount;

CustTable custTable;

int row;


AxeDataRecord _dataRecord;

Description busStreem,CostCenter,Country,Department,Importer,IntOrder,Region,SubPrg,TradePartner;

    DimensionAttributeValue             dimAttrBusStreemVal,dimAttrCostcenterVal,dimAttrCountryVal,dimAttrDepartmentVal,dimAttrImporterVal,

dimAttrIntOrderVal,dimAttrRegionVal,dimAttrSubPrgVal,dimAttrTradePartnerVal;

    DimensionAttribute                  dimAttrBusStreem,dimAttrCostcenter,dimAttrCountry,dimAttrDepartment,dimAttrImporter,

dimAttrIntOrder,dimAttrRegion,dimAttrSubPrg,dimAttrTradePartner;

    DimensionAttributeValueSetStorage  davss;

    boolean                             isValidDimension = true;



    DimensionDefault                    DefaultDimension;

    davss = DimensionAttributeValueSetStorage::find(DefaultDimension);

    dimAttrBusStreem        =   DimensionAttribute::findByName('Business_Stream');

dimAttrCostcenter       =   DimensionAttribute::findByName('CostCenter');

    dimAttrCountry          =   DimensionAttribute::findByName('Country');

dimAttrDepartment       =   DimensionAttribute::findByName('Department');

dimAttrImporter         =   DimensionAttribute::findByName('Importer');

dimAttrIntOrder         =   DimensionAttribute::findByName('InternalOrder');

dimAttrRegion           =   DimensionAttribute::findByName('Region');

dimAttrSubPrg           =   DimensionAttribute::findByName('SubProgram');

dimAttrTradePartner  =   DimensionAttribute::findByName('TradingPartners');



application = SysExcelApplication::construct();

workbooks = application.workbooks();

//specify the file path that you want to read

//filename = "C:\\Users\\v-kunaya\\Documents\\Vimal\\DIXF\\Final data imported into MST\\Customer_PrimaryAddress_FinDim1.xlsx";

filename = "C:\\Users\\v-kunaya\\Documents\\Vimal\\DIXF\\Final data imported into MST\\Customer_PrimaryAddressAX2009_FinDim1.xlsx";

//filename = "C:\\DMF\\DIXF_vimsin\\Ready to Import\\Imported on 26102015\\Customer_PrimaryAddress_FinDim7.xlsx";

try


{

workbooks.open(filename);

}

catch (Exception::Error)


{

throw error("File cannot be opened.");


}

workbook = workbooks.item(1);


worksheets = workbook.worksheets();

worksheet = worksheets.itemFromNum(1); //Here 1 is the worksheet Number which you can see like Sheet1


cells = worksheet.cells();

do


{

row++;
 
DefaultDimension = 0;

custAccount = cells.item(row, 1).value().bStr();

if (custAccount =="")

custAccount = any2str(cells.item(row, 1).value().double());

busStreem = cells.item(row, 2).value().bStr();

if (busStreem == "")

busStreem = any2str(cells.item(row, 2).value().double());

CostCenter = cells.item(row, 3).value().bStr();

if (CostCenter == "")

CostCenter = any2str(cells.item(row, 3).value().double());

Country = cells.item(row, 4).value().bStr();

if (Country == "")

Country = any2str(cells.item(row, 4).value().double());

Department = cells.item(row, 5).value().bStr();

if (Department == "")

Department = any2str(cells.item(row, 5).value().double());

Importer = cells.item(row, 6).value().bStr();

if (Importer == "")

Importer = any2str(cells.item(row, 6).value().double());

IntOrder = cells.item(row, 7).value().bStr();

if (IntOrder == "")

IntOrder = any2str(cells.item(row, 7).value().double());

Region = cells.item(row, 8).value().bStr();

if (Region == "")

Region = any2str(cells.item(row, 8).value().double());

SubPrg = cells.item(row, 9).value().bStr();

if (SubPrg == "")

SubPrg = any2str(cells.item(row, 9).value().double());

TradePartner = cells.item(row, 10).value().bStr();

if (TradePartner == "")

TradePartner = any2str(cells.item(row, 10).value().double());

dimAttrBusStreemVal   = DimensionAttributeValue::findByDimensionAttributeAndValueNoError(dimAttrBusStreem, busStreem, falsetrue);

dimAttrCostcenterVal   = DimensionAttributeValue::findByDimensionAttributeAndValueNoError(dimAttrCostcenter, CostCenter, false , true);

    dimAttrCountryVal   = DimensionAttributeValue::findByDimensionAttributeAndValueNoError(dimAttrCountry, Country, falsetrue);

dimAttrDepartmentVal   = DimensionAttributeValue::findByDimensionAttributeAndValueNoError(dimAttrDepartment, Department, falsetrue);

dimAttrImporterVal   = DimensionAttributeValue::findByDimensionAttributeAndValueNoError(dimAttrImporter, Importer, falsetrue);

dimAttrIntOrderVal   = DimensionAttributeValue::findByDimensionAttributeAndValueNoError(dimAttrIntOrder, IntOrder, falsetrue);

dimAttrRegionVal   = DimensionAttributeValue::findByDimensionAttributeAndValueNoError(dimAttrRegion, Region, falsetrue);

dimAttrSubPrgVal   = DimensionAttributeValue::findByDimensionAttributeAndValueNoError(dimAttrSubPrg, SubPrg, falsetrue);

dimAttrTradePartnerVal = DimensionAttributeValue::findByDimensionAttributeAndValueNoError(dimAttrTradePartner, TradePartner, falsetrue);

    if (dimAttrBusStreemVal)
    {
       davss.addItem(dimAttrBusStreemVal);
    }
 
    if (dimAttrCostcenterVal)


    {

        davss.addItem(dimAttrCostcenterVal);

    }

if (dimAttrCountryVal)


    {

        davss.addItem(dimAttrCountryVal);

    }

     if (dimAttrDepartmentVal)


    {

        davss.addItem(dimAttrDepartmentVal);

    }

if (dimAttrImporterVal)


    {

        davss.addItem(dimAttrImporterVal);

    }

     if (dimAttrIntOrderVal)


    {

        davss.addItem(dimAttrIntOrderVal);

    }

if (dimAttrRegionVal)


    {

        davss.addItem(dimAttrRegionVal);

    }

     if (dimAttrSubPrgVal)


    {

        davss.addItem(dimAttrSubPrgVal);

    }

if (dimAttrTradePartnerVal)


    {

        davss.addItem(dimAttrTradePartnerVal);

    }

if (dimAttrBusStreemVal || dimAttrCostcenterVal || dimAttrCountryVal || dimAttrDepartmentVal || dimAttrImporterVal


|| dimAttrIntOrderVal || dimAttrRegionVal || dimAttrSubPrgVal || dimAttrTradePartnerVal)

    {

        DefaultDimension =   davss.save();

    }

     else

         DefaultDimension = 0;

  
ttsBegin;

select forupdate custTable

where custTable.AccountNum == custAccount;

if(custTable && custTable.DefaultDimension == 0)


{

custTable.DefaultDimension = DefaultDimension;

custTable.update();

info(strFmt("%1 is updated",custAccount));


}

else

info(strFmt("%1 is not updated",custAccount));

ttsCommit;

 
type = cells.item(row+1, 1).value().variantType();



}

while (type != COMVariantType::VT_EMPTY);



application.quit();

}

Import/Update Financial dimension through available table's data

Job: public DimensionDefault findDefaultDimId(AxeDataRecord _dataRecord)
{
    DimensionAttributeValue             dimCostcenterVal,dimDepartmentVal;
    DimensionAttribute                  dimAttrCostcenter,dimAttrDepartment;
    DimensionAttributeValueSetStorage   davss;
    boolean                             isValidDimension = true;
    DimensionDefault                    DefaultDimension; 
    davss = DimensionAttributeValueSetStorage::find(DefaultDimension);
    dimAttrCostcenter           =   DimensionAttribute::findByName('CostCenter');
    dimAttrDepartment           =   DimensionAttribute::findByName('Department'); 
   dimCostcenterVal      =   DimensionAttributeValue::findByDimensionAttributeAndValueNoError(dimAttrCostcenter, _dataRecord.value('Dimension2_'), false , true);
    dimDepartmentVal      =   DimensionAttributeValue::findByDimensionAttributeAndValueNoError(dimAttrDepartment, _dataRecord.value('Dimension') , false, true);
    if(dimCostcenterVal )
    {
        davss.addItem(dimCostcenterVal);
    }
    if (dimDepartmentVal)
    {
        davss.addItem(dimDepartmentVal);
    }
    if(dimCostcenterVal || dimDepartmentVal)
    {
        DefaultDimension =   davss.save();
 
        return DefaultDimension;
    }
    else
        return 0;
}

Tuesday, 20 October 2015

How to Create/Update/Find a phone number for a customer/vendor in X++ [AX 2012]

As a follow-up to my last post about finding phone numbers, here is sample code of how you can properly find/create/update a phone number for a customer/vendor.

Case- 1: Creating or updating phone number for a customer/vendor


static void CreatePhoneExample(Args _args)
{
    CustTable                           custTable = CustTable::find('100013'); // TODO - Change to your customer
    LogisticsElectronicAddress          logisticsElectronicAddress;
    container                           defaultRole = map2Con(LogisticsLocationEntity::getDefaultLocationRoleFromEntity(tableNum(DirPartyTable)));
    
    setPrefix(strFmt("Creating/Updating number for customer %1", custTable.AccountNum));
    
    // This will find/create a number for a customer
    ttsBegin;
    logisticsElectronicAddress.Type = LogisticsElectronicAddressMethodType::Phone;
    logisticsElectronicAddress.Locator = '555-555-5555';
    
    logisticsElectronicAddress.Location = DirPartyLocation::findOrCreate(custTable.Party, 0).Location;

    // This will find or create the new logisticsElectronicAddress
    // If it does not find it, it will do a .insert() which will only persist these fields (Location, Type, Locator, LocatorExtension)
    // so if you want to set the Description or if it's primary or not, you will need to update the record after this call
    logisticsElectronicAddress = LogisticsElectronicAddress::findOrCreate(logisticsElectronicAddress);
    
    // We re-select it for update in case this isn't a new number and it found an existing
    // because the "find" doesn't "select for update"
    logisticsElectronicAddress = LogisticsElectronicAddress::findRecId(logisticsElectronicAddress.RecId, true);
    
    logisticsElectronicAddress.Description = "New Primary Phone";
    
    // If you set the number to primary, during the insert/update it will handle unassigning previously
    // marked primary numbers if they exist
    logisticsElectronicAddress.IsPrimary = NoYes::Yes;
    
    logisticsElectronicAddress.update();
    
    // At this point, we need to mark the "purpose" of the number.  I'm just using the default role, which should be "Business"
    LogisticsEntityLocationRoleMap::createEntityLocationRoles(tableNum(LogisticsElectronicAddressRole), logisticsElectronicAddress.RecId, conPeek(defaultRole, 1), true);
    
    info(strFmt("Created/updated phone number [%1] for customer %2.", logisticsElectronicAddress.Locator, custTable.AccountNum));
    ttsCommit;
}

Case- 1: Finding phone number for a customer/vendor

Method-1:
Display LogisticsElectronicAddressLocator Phone() { LogisticsElectronicAddress logisticsElectronicAddress; //return LogisticsElectronicAddress::findByLocation(DirPartyLocation::findOrCreate(this.Party, 0).Location).Locator; select Location, Type, Locator from logisticsElectronicAddress where logisticsElectronicAddress.Location == DirPartyLocation::findOrCreate(this.Party, 0).Location && logisticsElectronicAddress.Type == LogisticsElectronicAddressMethodType::Phone; Return logisticsElectronicAddress.Locator; }
Note: Here this.Party may refer to MSDirPartyPostalAddressView.Party or CustTable/VendTable.Party;
Method-2:
Display Description PhoneDescription() { LogisticsElectronicAddress logisticsElectronicAddress; //return LogisticsElectronicAddress::findByLocation(DirPartyLocation::findOrCreate(this.Party, 0).Location).Locator; select Location, Type, Locator from logisticsElectronicAddress where logisticsElectronicAddress.Location == DirPartyLocation::findOrCreate(this.Party, 0).Location && logisticsElectronicAddress.Type == LogisticsElectronicAddressMethodType::Phone; Return logisticsElectronicAddress.Description; }
Note: Here also this.Party may refer to MSDirPartyPostalAddressView.Party or CustTable/VendTable.Party;
Happy DAXing.....

The Table.Field does not have a corresponding parm-method on the AxBC-class

If you add new field in a table and getting "The Table.Field does not have a corresponding parm-method on the AxBC-class" error message, you can run following Job to fix this issue. This job will add corresponding parm-method for newly added field in a table.

static void CreateAxBCParmMethodJob(Args _args)

    axGenerateAxBCClass axGenerateAxBCClass; 

    axGenerateAxBCClass = AxGenerateAxBCClass::newTableId(tablenum(CustTable));
    axGenerateAxBCClass.run(); 
 
}

Friday, 9 October 2015

The Table.Field does not have a corresponding parm-method on the AxBC-class

If you add new field in a table and getting "The Table.Field does not have a corresponding parm-method on the AxBC-class" error message, you can run following Job to fix this issue. This job will add corresponding parm-method for newly added field in a table.

static void CreateAxBCParmMethodJob(Args _args)

    axGenerateAxBCClass axGenerateAxBCClass; 

    axGenerateAxBCClass = AxGenerateAxBCClass::newTableId(tablenum(CustTable));
    axGenerateAxBCClass.run();  
}

Happy DAXing....

Thursday, 1 October 2015

How to get/ fetch Sales Price (SalesPrice) from sales Trade agreement in AX 2012

Hi Guys,
Now a days I am working on Interfaces like Import order from xml into AX 2012 Sales order so here, I will share with you the logic for picking Sales price from trade agreement in ax 2012.

Firstly, I tested the values through a job, like:
static void priceFromAgreement(Args _args)
{
    PriceDiscTable      priceDiscTable;
    //PriceDiscAdmTrans   _trans;
    ItemId              itemRelation = "021-08221";
    CustAccount         accountRelation = "1652-000007";
    real                salesPrice1, salesPrice2, salesPrice3;
    PriceType           relation = PriceType::PriceSales;
    NoYes               _RelationExist = NoYes::No;

    /// First if  trade agreement exist for Item for customer
    select firstonly priceDiscTable
        where priceDiscTable.Relation           == relation
           && priceDiscTable.ItemCode           == TableGroupAll::Table
           && priceDiscTable.ItemRelation       == itemRelation
           && priceDiscTable.AccountCode        == TableGroupAll::Table
           && priceDiscTable.AccountRelation    == accountRelation;

    salesPrice1 = priceDiscTable.Amount;
    info(strFmt("salesPrice1: %1", salesPrice1));

    if (priceDiscTable !=null)
    {
        info(strFmt("found Price1: %1", priceDiscTable.Amount));
    }

    // trade agreement exist for particular item for particular customer
    select firstonly priceDiscTable
        where priceDiscTable.Relation           == relation
           && priceDiscTable.ItemCode           == TableGroupAll::Table
           && priceDiscTable.ItemRelation       == itemRelation
           && priceDiscTable.AccountCode        == TableGroupAll::GroupId
           && priceDiscTable.AccountRelation    == "ROC";

    salesPrice2 = priceDiscTable.Amount;
    info(strFmt("salesPrice2: %1", salesPrice2));

    if (priceDiscTable !=null)
    {
        info(strFmt("found Price2: %1", priceDiscTable.Amount));
    }

    // third possibility is that when Customer have to all product with same price of amount.
    select firstonly priceDiscTable
        where priceDiscTable.Relation           == relation
           && priceDiscTable.ItemCode           == TableGroupAll::Table
           && priceDiscTable.ItemRelation       == itemRelation
           && priceDiscTable.AccountCode        == TableGroupAll::All
           && priceDiscTable.AccountRelation    == " ";

    salesPrice3 = priceDiscTable.Amount;
    info(strFmt("salesPrice3: %1", salesPrice3));

    if (priceDiscTable !=null)
    {
        info(strFmt("found Price3: %1", priceDiscTable.Amount));
    }
}


Now testing is done, we can start our development, Steps are as:

Step-1: Create one method to find PriceDiscTable object

public static PriceDiscTable findPriceDiscTable(PriceDiscAccountCode        _accountCode,
                                                PriceDiscAccountRelation    _accountRelation,
                                                PriceDiscItemCode           _itemCode,
                                                PriceDiscItemRelation       _itemRelation)
{
    PriceDiscTable      priceDiscTable;
    InventSiteId        inventSiteId;
    PriceType           relation = PriceType::PriceSales;

    inventSiteId = InventDim::find(priceDiscTable.InventDimId).InventSiteId;

    select firstonly priceDiscTable
        where priceDiscTable.Relation           == relation
           && priceDiscTable.AccountCode        == _accountCode
           && priceDiscTable.AccountRelation    == _accountRelation
           && priceDiscTable.ItemCode           == _itemCode
           && priceDiscTable.ItemRelation       == _itemRelation
           && priceDiscTable.ToDate             == dateNull();

    return priceDiscTable;
}

Step-2: Create another method to specify scenarios (cases) which may be described and will run on the basis of that trade agreement. Create cases as required as:

public static PriceDiscTable checkPriceDiscTable(PriceDiscAccountRelation    _accountRelation,
                                                 PriceDiscItemRelation       _itemRelation)
{
    PriceDiscTable              priceDiscTableRec;
    TableGroupAll               accountCode, ItemCode;
    PriceDiscAccountRelation    accountRelation;
    PriceDiscItemRelation       itemRelation;

    int     totalcases = 3;
    int     prioritycase = 0;

    while(prioritycase < totalcases)
    {
        switch (priorityCase)
        {
            case 0:
                accountCode         = TableGroupAll::Table;
                accountRelation     = _accountRelation;
                itemCode            = TableGroupAll::Table;
                itemRelation        = _itemRelation;

                priceDiscTableRec = MSSalesInterfaceLaffvlo::findPriceDiscTable(accountCode, accountRelation,
                                                                                itemCode, itemRelation);
                if(priceDiscTableRec.recId)
                {
                    return priceDiscTableRec;
                }
                break;

            case 1:
                accountCode         = TableGroupAll::GroupId;
                accountRelation     = _accountRelation;
                itemCode            = TableGroupAll::Table;
                itemRelation        = _itemRelation;

                priceDiscTableRec = MSSalesInterfaceLaffvlo::findPriceDiscTable(accountCode, accountRelation,
                                                                                itemCode, itemRelation);
                if(priceDiscTableRec.recId)
                {
                    return priceDiscTableRec;
                }
                break;

            case 2:
                accountCode         = TableGroupAll::All;
                accountRelation     = " ";
                itemCode            = TableGroupAll::Table;
                itemRelation        = _itemRelation;

                priceDiscTableRec = MSSalesInterfaceLaffvlo::findPriceDiscTable(accountCode, accountRelation,
                                                                                itemCode, itemRelation);
                if(priceDiscTableRec.recId)
                {
                    return priceDiscTableRec;
                }
                break;
        }
        prioritycase++;
    }

    return priceDiscTableRec;
}


Step-3: Add logic in Insert method from where values are getting inserted....

public static void insertLaffvloLineData(Container _value, MSSalesTable _mSSalesTable)
{
    MSSalesLine         salesline;
    InventTable         inventTable;
    InventDim           inventDim, inventDimLoc;
    PriceDiscTable      priceDiscTable;

    salesline.ItemId        = conPeek(_value, 22);
    salesline.ProductId     = conPeek(_value, 22);
    salesline.ProductName   = conPeek(_value, 7);
    salesline.Qty           = conPeek(_value, 9);
    salesline.CurrencyCode  = _mSSalesTable.CurrencyCode;
    salesline.MSSalesTable  = _mSSalesTable.RecId;  
 
    inventTable             = InventTable::find(salesline.ItemId);
    inventDim.InventSiteId  = inventTable.inventItemSalesSetup().inventDim().InventSiteId;
    inventDimLoc            = InventDim::findOrCreate(inventTable.inventItemSalesSetup().inventDim());

    priceDiscTable = MSSalesInterfaceLaffvlo::checkPriceDiscTable(_mSSalesTable.CustAccount, salesline.ItemId);
    salesline.SalesPrice = priceDiscTable.Amount;
 
    /*salesline.SalesPrice   = conPeek(PriceDisc::findItemPriceAgreement(ModuleInventPurchSales::Sales,
                                        salesline.ItemId,
                                        inventdim,
                                        "EA",
                                        today(),
                                        salesline.Qty,
                                       _mSSalesTable.CustAccount,
                                        'USD',
                                        CustTable::find(_mSSalesTable.CustAccount).PriceGroup), 1);*/

    if (!salesline.SalesPrice)
    {
        salesline.SalesPrice = InventItemPrice::findCurrent(salesline.ItemId,
                                                            CostingVersionPriceType::Sales,
                                                            inventdim.InventDimId,
                                                            today(),
                                                            inventdim.InventSiteId).Price;

        if (!salesline.SalesPrice)
            salesline.SalesPrice = InventTable::find(salesline.ItemId).salesPcsPrice();
    }

    salesline.LineAmount = salesline.Qty * salesline.SalesPrice;

    salesline.insert();
}


Note: Yeah, let me clear you on the SalesPrice scenarios

  1. If Trade agreement is created what we need then it should be 1st priority to fetch price from there
  2. If not then SalesPrice should be picked from Costing Version
  3. If not then lastly, SalesPrice should be picked up from Item base price (Item master- released products)
I tried to clarify from my best.

Thanx.
Happy DAXing.....

Friday, 11 September 2015

Address Import in AX 2012

Here, I got the job for importing address masters like CountryId, State, ZipCode, City... I am sharing with DAX techies hope it will help you.

static void AddressImport(Args _args)
{
    SysExcelApplication               application;
    SysExcelWorkbooks               workbooks;
    SysExcelWorkbook                workbook;
    SysExcelWorksheets              worksheets;
    SysExcelWorksheet               worksheet;
    SysExcelCells                        cells;
    COMVariantType                  type;
    Name                                     name;
    FileName                               filename;
    InventPosting                         InventPosting;

    DimensionAttributeValueCombination DimensionAttributeValueCombination;

    int row =1;
    LogisticsAddressZipCode          zipCode;
    LogisticsAddressZipCodeId        zipCodeId;
    LogisticsAddressCity             city;
    LogisticsAddressStateId          stateId;
    LogisticsAddressState            state;
    LogisticsAddresssCity            cityRecord;
    LogisticsAddressCountyName       countyName;
    LogisticsAddressCountyId         countyId;
    LogisticsAddressCounty           county;

    boolean                          badRecord;
    int                              i=1;
    int                              numProcessedRecords=0;
    LogisticsAddressCountryRegionId  _countryRegionId;

    //LogisticsAddressStateId          stateId;
    //LogisticsAddressCountyId         countyId;
    //LogisticsAddressCountyName       countyName;
   
    application = SysExcelApplication::construct();
    workbooks   = application.workbooks();
   
    //specify the file path that you want to read
    filename    = "C:\\Users\\v-vimsin\\Documents\\Vimal\\DIXF\\LogisticsPostalAddress - Copy.xlsx";
    try
    {
        workbooks.open(filename);
    }
    catch (Exception::Error)
    {
        throw error("File cannot be opened.");
    }
   
    ttsbegin;
    workbook    = workbooks.item(1);
    worksheets  = workbook.worksheets();
    worksheet   = worksheets.itemFromNum(1); //Here 3 is the worksheet Number
    cells       = worksheet.cells();
   
    do
    {
        row++;
        zipCodeId        = cells.item(row, 4).value().bStr();
        if (zipCodeId == "")
            zipCodeId = int2str(cells.item(row, 4).value().double());
       
        stateId          = cells.item(row, 3).value().bStr();
        city             = cells.item(row, 2).value().bStr();
        _countryRegionId = cells.item(row, 1).value().bStr();
        countyId         = cells.item(row, 5).value().bStr();
       
        if (stateId != '')
            state= LogisticsAddressState::find(_countryRegionId, stateId);  
            if (!state.RecId)
            {
                state.CountryRegionId   = _countryRegionId;
                state.StateId           = stateId;
                state.insert();
            }
            // Check if county exists
            //if(countyId != '')
            county = LogisticsAddressCounty::find(_countryRegionId, stateId, countyId);
   
            if (city != '')
            {
                select firstonly cityRecord where
                    cityRecord.Name             == city &&
                    cityRecord.StateId          == stateId &&
                    cityRecord.CountryRegionId  == _countryRegionId &&
                    cityRecord.CountyId         == countyId;
            }

            if (!cityRecord.RecId)
            {
                cityRecord.CountryRegionId  = _countryRegionId;
                cityRecord.Name             = city;
                cityRecord.StateId          = stateId;
                cityRecord.CountyId         = countyId;
                cityRecord.insert();
            }

            select firstonly zipCode where
                zipCode.ZipCode         == zipCodeId &&
                zipCode.State           == stateId &&
                zipCode.County          == countyId &&
                zipCode.CountryRegionId == _countryRegionId &&
                zipCode.CityRecId       == cityRecord.RecId;

            if (!zipCode.RecId)
            {
                zipCode.ZipCode         = zipCodeId;
                zipCode.City            = city;
                zipCode.CityRecId       = cityRecord.RecId;
                zipCode.CountryRegionId = _countryRegionId;
                zipCode.State           = stateId;
                zipCode.County          = countyId;
                zipCode.insert();

                numProcessedRecords++;
            }

        type = cells.item(row+1, 1).value().variantType();
    }

    while (type != COMVariantType::VT_EMPTY);

    info(strFmt("%1 Inserted",numProcessedRecords));

    ttsCommit;

    application.quit();
}

Happy DAXing.....