I am new to Excel VBA scripting below are the issue I am facing :
1) Picking Material number from the excel cell and passing to the sales order created BAPI.
Data declaration
Dim Material As String
Material = ActiveSheet.Range("E14")
oItemsIn.Value(1, "MATERIAL") = Material
In This case the error message is there "Material 2094266 does not exist in sales area"
but if I pass material "000000000002094266" then it work fine
How I can change the format with leading Zero in the material number after picking value from the cell?
2) How I can pass material config (variant config) for the line item I am passing below values
Set CFGS_REF = oBapiCtrl.DimAs(boOrder, "CreateFromData", "OrderCfgsRef")
Set CFGS_VK = oBapiCtrl.DimAs(boOrder, "CreateFromData", "OrderCfgsInst")
Set CFGS_VALUE = oBapiCtrl.DimAs(boOrder, "CreateFromData", "OrderCfgsValue")
'OrderCfgsRefinst
CFGS_REF.Value("POSEX") = "000010"
CFGS_REF.Value("CONFIG_ID") = "000010"
CFGS_REF.Value("ROOT_ID") = "00000010"
' forOrderCfgsVk
CFGS_VK.Value("CONFIG_ID") = "000010"
CFGS_VK.Value("INST_ID") = "00000010"
CFGS_VK.Value("CLASS_TYPE") = "300"
'OrderCfgsValue
CFGS_VALUE.Value("CONFIG_ID") = "000010"
CFGS_VALUE.Value("INST_ID") = "00000010" ' Item
CFGS_VALUE.Value("CHARC") = "PRG_ORD_SOURCE"
CFGS_VALUE.Value("Value") = "Excel"
But it throws an error of data mismatch at CFGS_REF.Value("POSEX") = "000010"
To add the leading zeroes back to your material number:
oItemsIn.Value(1, "MATERIAL") = Format(Material, "000000000000000000")
Related
I am struggling with figuring out how to iterate through the src values of a class name. These are gallery images and there are anywhere from 0 to 10 additional images for each product on a page. I am scraping the content so we can add these products to our site as an authorized distributor. The vendor does not provide the data in a format we can easily import.
Set objDescShort = doc.getelementsbyclassname("single__short-description")(0)
Set objDescLong = doc.getelementsbyclassname("ui-tabs-panel ui-corner-bottom ui-widget-content")(0)
Set objImgUrl = doc.getelementsbyclassname("single__gallery-main-img")(0) 'main image
Set objImgUrl2 = doc.getelementsbyclassname("single__gallery-thumbs-img")(0) 'gallery images
ret1 = objDescShort.innerHTML
ret2 = objDescLong.innerHTML
mysheet.Cells(n, 7).Value = ret1
mysheet.Cells(n, 8).Value = ret2
ret3 = objImgUrl.src
mysheet.Cells(n, 9).Value = ret3
galimg = ""
ret4 = doc.getelementsbyclassname("single__gallery-thumbs-img")
For Each srcElm In ret4
galimg = srcElm.src & ", " & galimg
Next
mysheet.Cells(n, 10).Value = galimg
This is just a small section of my code. The url from which I'm extracting this data is http://www.tigertoughgroup.com/products/T62130/
I am having a hard time figuring out what the correct syntax is to get the 'src' values from each 'img' tag in this class.
First, since getElementsByClassName returns a collection of elements, you'll need to use the keyword Set to assign those objects to your variable...
Set ret4 = doc.getelementsbyclassname("single__gallery-thumbs-img")
Then you can use getAttribte to get the src value...
srcElm.getAttribute("src")
Hope this helps!
I'm trying to find a way to automate data entry into the raise invoice screen in Sage 50.
All of our order data is held in a different system and we could easily pull together the line items, customer data, etc. automatically but our accounts team currently have to manually select each row, enter the SKU and quantity which is very time consuming.
It appears that the clipboard isn't functional in the Product Code field either - which is really annoying!
Are there any reasonable ways to inject data like this into Sage 50?
as far as i know there is a Excel2Sage Tool or App which can handle mass-importing. i did not used the commercial software last year, but the year before.
i'm actual not know about a free solution for this without developing it.
As alternative you could use AutoIt or something.
best
Eric
Here is an example using VB.Net:
'Declare objects
Dim oSDO As SageDataObject230.SDOEngine
Dim oWS As SageDataObject230.WorkSpace
Dim oSOPRecord As SageDataObject230.SopRecord
Dim oSOPItem_Read As SageDataObject230.SopItem
Dim oSOPItem_Write As SageDataObject230.SopItem
Dim oSOPPost As SageDataObject230.SopPost
Dim oStockRecord As SageDataObject230.StockRecord
'Declare Variables
Dim szDataPath As String
'Create SDO Engine Object
oSDO = New SageDataObject230.SDOEngine
' Select company. The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\Documents and Settings\All Users\Application Data\Sage\Accounts\2017\")
'Create Workspace
oWS = oSDO.Workspaces.Add("Example")
'Try to connect
If oWS.Connect(szDataPath, "manager", "", "Example") Then
'Create objects
oSOPRecord = oWS.CreateObject("SOPRecord")
oSOPPost = oWS.CreateObject("SOPPost")
oSOPItem_Read = oWS.CreateObject("SOPItem")
oStockRecord = oWS.CreateObject("StockRecord")
'Read an existing Sales Order
oSOPRecord.MoveLast()
'Populate the order header, copying fields from oSOPRecord to oSOPPost
oSOPPost.Header("INVOICE_NUMBER").Value = oSOPRecord.Fields.Item("INVOICE_NUMBER").Value
oSOPPost.Header("ACCOUNT_REF").Value = CStr(oSOPRecord.Fields.Item("ACCOUNT_REF").Value)
oSOPPost.Header("NAME").Value = CStr(oSOPRecord.Fields.Item("NAME").Value)
oSOPPost.Header("ADDRESS_1").Value = CStr(oSOPRecord.Fields.Item("ADDRESS_1").Value)
oSOPPost.Header("ADDRESS_2").Value = CStr(oSOPRecord.Fields.Item("ADDRESS_2").Value)
oSOPPost.Header("ADDRESS_3").Value = CStr(oSOPRecord.Fields.Item("ADDRESS_3").Value)
oSOPPost.Header("ADDRESS_4").Value = CStr(oSOPRecord.Fields.Item("ADDRESS_4").Value)
oSOPPost.Header("ADDRESS_5").Value = CStr(oSOPRecord.Fields.Item("ADDRESS_5").Value)
oSOPPost.Header("DEL_ADDRESS_1").Value = CStr(oSOPRecord.Fields.Item("DEL_ADDRESS_1").Value)
oSOPPost.Header("DEL_ADDRESS_2").Value = CStr(oSOPRecord.Fields.Item("DEL_ADDRESS_2").Value)
oSOPPost.Header("DEL_ADDRESS_3").Value = CStr(oSOPRecord.Fields.Item("DEL_ADDRESS_3").Value)
oSOPPost.Header("DEL_ADDRESS_4").Value = CStr(oSOPRecord.Fields.Item("DEL_ADDRESS_4").Value)
oSOPPost.Header("DEL_ADDRESS_5").Value = CStr(oSOPRecord.Fields.Item("DEL_ADDRESS_5").Value)
oSOPPost.Header("CUST_TEL_NUMBER").Value = CStr(oSOPRecord.Fields.Item("CUST_TEL_NUMBER").Value)
oSOPPost.Header("CONTACT_NAME").Value = CStr(oSOPRecord.Fields.Item("CONTACT_NAME").Value)
oSOPPost.Header("GLOBAL_TAX_CODE").Value = CShort(oSOPRecord.Fields.Item("GLOBAL_TAX_CODE").Value)
oSOPPost.Header("ORDER_DATE").Value = CDate(oSOPRecord.Fields.Item("ORDER_DATE").Value)
oSOPPost.Header("NOTES_1").Value = CStr(oSOPRecord.Fields.Item("NOTES_1").Value)
oSOPPost.Header("NOTES_2").Value = CStr(oSOPRecord.Fields.Item("NOTES_1").Value)
oSOPPost.Header("NOTES_3").Value = CStr(oSOPRecord.Fields.Item("NOTES_3").Value)
oSOPPost.Header("TAKEN_BY").Value = CStr(oSOPRecord.Fields.Item("TAKEN_BY").Value)
oSOPPost.Header("ORDER_NUMBER").Value = CStr(oSOPRecord.Fields.Item("ORDER_NUMBER").Value)
oSOPPost.Header("CUST_ORDER_NUMBER").Value = CStr(oSOPRecord.Fields.Item("CUST_ORDER_NUMBER").Value)
oSOPPost.Header("PAYMENT_REF").Value = CStr(oSOPRecord.Fields.Item("PAYMENT_REF").Value)
oSOPPost.Header("GLOBAL_NOM_CODE").Value = CStr(oSOPRecord.Fields.Item("GLOBAL_NOM_CODE").Value)
oSOPPost.Header("GLOBAL_DETAILS").Value = CStr(oSOPRecord.Fields.Item("GLOBAL_DETAILS").Value)
oSOPPost.Header("ORDER_TYPE").Value = oSOPRecord.Fields.Item("ORDER_TYPE").Value
oSOPPost.Header("FOREIGN_RATE").Value = CDbl(oSOPRecord.Fields.Item("FOREIGN_RATE").Value)
oSOPPost.Header("CURRENCY").Value = oSOPRecord.Fields.Item("CURRENCY").Value
oSOPPost.Header("CURRENCY_USED").Value = oSOPRecord.Fields.Item("CURRENCY_USED").Value
' Link header to items
oSOPItem_Read = oSOPRecord.Link
'Find the First Record
oSOPItem_Read.MoveFirst()
Do
'Add the existing items to the order
oSOPItem_Write = oSOPPost.Items.Add
'Populate the Fields, copying the data from the existing records
oSOPItem_Write.Fields.Item("STOCK_CODE").Value = CStr(oSOPItem_Read.Fields.Item("STOCK_CODE").Value)
oSOPItem_Write.Fields.Item("DESCRIPTION").Value = CStr(oSOPItem_Read.Fields.Item("DESCRIPTION").Value)
oSOPItem_Write.Fields.Item("NOMINAL_CODE").Value = CStr(oSOPItem_Read.Fields.Item("NOMINAL_CODE").Value)
oSOPItem_Write.Fields.Item("TAX_CODE").Value = CShort(oSOPItem_Read.Fields.Item("TAX_CODE").Value)
oSOPItem_Write.Fields.Item("QTY_ORDER").Value = CDbl(oSOPItem_Read.Fields.Item("QTY_ORDER").Value)
oSOPItem_Write.Fields.Item("UNIT_PRICE").Value = CDbl(oSOPItem_Read.Fields.Item("UNIT_PRICE").Value)
oSOPItem_Write.Fields.Item("NET_AMOUNT").Value = CDbl(oSOPItem_Read.Fields.Item("NET_AMOUNT").Value)
oSOPItem_Write.Fields.Item("TAX_AMOUNT").Value = CDbl(oSOPItem_Read.Fields.Item("TAX_AMOUNT").Value)
oSOPItem_Write.Fields.Item("COMMENT_1").Value = CStr(oSOPItem_Read.Fields.Item("COMMENT_1").Value)
oSOPItem_Write.Fields.Item("COMMENT_2").Value = CStr(oSOPItem_Read.Fields.Item("COMMENT_2").Value)
oSOPItem_Write.Fields.Item("UNIT_OF_SALE").Value = CStr(oSOPItem_Read.Fields.Item("UNIT_OF_SALE").Value)
oSOPItem_Write.Fields.Item("FULL_NET_AMOUNT").Value = CDbl(oSOPItem_Read.Fields.Item("FULL_NET_AMOUNT").Value)
oSOPItem_Write.Fields.Item("TAX_RATE").Value = CDbl(oSOPItem_Read.Fields.Item("TAX_RATE").Value)
'We now need to ensure that the TAX_FLAG is set the same as the item being read otherwise it will be re calculated
oSOPItem_Write.Fields.Item("TAX_FLAG").Value = CInt(oSOPItem_Read.Fields.Item("TAX_FLAG").Value)
'Loop until there are no more existing items
Loop Until oSOPItem_Read.MoveNext = False
'destroy the oSOPItem_Write object
oSOPItem_Write = Nothing
'write a new item
oStockRecord.MoveLast()
oSOPItem_Write = oSOPPost.Items.Add
' Populate other fields required for Invoice Item
' From 2015 the update method now wraps internal business logic
' that calculates the vat amount if a net amount is given.
' If you wish to calculate your own Tax values you will need
' to ensure that you set the TAX_FLAG to 1 and set the TAX_AMOUNT value on the item line
' ***Note if a NVD is set the item line values will be recalculated
' regardless of the Tax_Flag being set to 1***
oSOPItem_Write.Fields.Item("STOCK_CODE").Value = oStockRecord.Fields.Item("STOCK_CODE").Value
oSOPItem_Write.Fields.Item("DESCRIPTION").Value = CStr(oStockRecord.Fields.Item("DESCRIPTION").Value)
oSOPItem_Write.Fields.Item("NOMINAL_CODE").Value = CStr(oStockRecord.Fields.Item("NOMINAL_CODE").Value)
oSOPItem_Write.Fields.Item("TAX_CODE").Value = CShort(oStockRecord.Fields.Item("TAX_CODE").Value)
oSOPItem_Write.Fields.Item("QTY_ORDER").Value = CDbl(2)
oSOPItem_Write.Fields.Item("UNIT_PRICE").Value = CDbl(50)
oSOPItem_Write.Fields.Item("NET_AMOUNT").Value = CDbl(100)
oSOPItem_Write.Fields.Item("FULL_NET_AMOUNT").Value = CDbl(100)
oSOPItem_Write.Fields.Item("COMMENT_1").Value = CStr("")
oSOPItem_Write.Fields.Item("COMMENT_2").Value = CStr("")
oSOPItem_Write.Fields.Item("UNIT_OF_SALE").Value = CStr("")
oSOPItem_Write.Fields.Item("TAX_RATE").Value = CDbl(20)
'Destroy the oSOPItem_Write object
oSOPItem_Write = Nothing
'Post the order
If oSOPPost.Update() Then
MsgBox("Order Updated Successfully")
Else
MsgBox("Order Update Failed")
End If
'Disconnect and destroy the objects
oWS.Disconnect()
oSDO = Nothing
oWS = Nothing
oSOPRecord = Nothing
oSOPItem_Read = Nothing
oSOPItem_Write = Nothing
oSOPPost = Nothing
oStockRecord = Nothing
End If
Exit Sub
All of the current commercial products will require you to put your data into a specific format (column order and file type) anyway, so if you can do that, then bring everything into Excel, and then adapt the code listed above for VB.Net into VBA. It's fairly straightforward, mainly passing data to an array and then looping through.
If you want specific assistance, show us the structure of your Order data, and then we can do something
Cheers
Paul
I've a problem when I run simple add-on into SAP Business One. I've gotten this exception through this snippet of this code :
' After changing the item quantity
If (pVal.ItemUID = "mat") And (pVal.ColUID = "ActQuan") And (pVal.EventType = SAPbouiCOM.BoEventTypes.et_VALIDATE) Then
Dim oEditPrice As SAPbouiCOM.EditText ' Item Price
Dim oEditTDTotal As SAPbouiCOM.EditText ' To Date Total
Dim oEditTDQuan As SAPbouiCOM.EditText ' To Date Quan
Dim oEditCuttings As SAPbouiCOM.EditText ' Cuttings
Dim oEditTotal As SAPbouiCOM.EditText ' Total = TDTotal - Cuttings
Dim oEditActQuan As SAPbouiCOM.EditText
' Get the items from the matrix
oEditPrice = colItemPrice.Cells.Item(pVal.Row).Specific
oEditTDTotal = colItemTDTotal.Cells.Item(pVal.Row).Specific
oEditTDQuan = colItemTDQuan.Cells.Item(pVal.Row).Specific
oEditTotal = colItemACuttings.Cells.Item(pVal.Row).Specific
oEditCuttings = colItemCuttings.Cells.Item(pVal.Row).Specific
oEditActQuan = colItemActQuan.Cells.Item(pVal.Row).Specific
' Copy the value of TDQty
Dim tmpInt As Integer
tmpInt = CInt(oEditActQuan.Value)
oEditTDQuan.Value = CInt(tmpInt)
' Copy the value of TDTotal
Dim tmpIn As Integer
tmpIn = CInt(oEditTDQuan.Value) * CInt(oEditPrice.Value)
oEditTDTotal.Value = CInt(tmpIn)
'Calc Total Row - ACuts
Dim tmpTotal As Integer ' temp variable to contain total result
tmpTotal = CInt(oEditTDTotal.Value) - CInt(oEditCuttings.Value)
oEditTotal.Value = CInt(tmpTotal)
' Calc the document total
Dim CalcTotal As Double
Dim i As Integer
CalcTotal = 0
' Iterate all the matrix rows
For i = 1 To oMatrix.RowCount
oEditTotal = colItemACuttings.Cells.Item(i).Specific
CalcTotal += oEditTotal.Value
Next
oDocTotal.Value = CalcTotal
End If
End If
End If
I use VB.Net. I have an issue with ColUID = "ActQuan" . Can anyone help me ?
I changed this column many times and the same error.
Not the exact same thing, but in sap, we get this RPC_E_SERVERFAULT issue when sap scripting settings are not correct. The following changes worked for me:
Open transaction RZ11
Set the following to true:
sapgui/user_scripting
Set the following to false:
sapgui/nwbc_scripting
sapgui/user_scripting_disable_recording
sapgui/user_scripting_force_notification
sapgui/user_scripting_per_user
sapgui/user_scripting_set_readonly
Enable user side scripting.
More detailed documentation can be found here.
I need to export the Catia Spec tree to use as a BoM.
The Export Should:
Go to Excel and will use the WalkDownTree function.
Have the PartNumber, Nomenclature and a User Added
Property called "Sinex Ref".
It will also have to make sure that the Exported Tree ignores Parts
and Products called "Ref".
Present the Quantity of each item using the
PartNumber.
Include the deactivated parts but mention that they
are deactivated.
I'm new to Catia and VBA and have come up with the following (I made adjustments to other macros that i have found but noticed that they ignore the children in the Tree). Currently the macro generates the Excel file and in the same cell cycles through all of the parts and children in the spec tree, regardless if they're deactivated or not.
Sub CATMain()
' ********* is the current document a CATIA Product **************
If CATIA.Documents.Count = 0 Then
MsgBox "There are no CATIA documents open. Please open a CATIA document and try again.", ,msgboxtext
Exit Sub
End If
If InStr(CATIA.ActiveDocument.Name, ".CATProduct") < 1 Then
MsgBox "The active document is not a Product. Please open a CATIA Product and try again.", ,msgboxtext
Exit Sub
End If
' ************* General declarations for the Active CATIA session *****************
Dim oProdDoc As ProductDocument
t = 1
Set oProdDoc = CATIA.ActiveDocument
Dim oRootProd As Product
Set oRootProd = oProdDoc.Product
Dim par As Parameters
Set par = oRootProd.UserRefProperties
Dim SinexRef As String
' *************** begin spec tree scroll ******************
Call WalkDownTree(oRootProd)
End Sub
Sub WalkDownTree(oInProduct As Product)
Dim oInstances As Products
Set oInstances = oInProduct.Products
On Error Resume Next
Set Excel = GetObject(, "EXCEL.Application")
If Err.Number <> 0 Then
Set Excel = CreateObject("EXCEL.Application")
Excel.Visible = True
Excel.Workbooks.Add
End If
If t <> 1 Then
for i=1 to oInProduct.Count
'**************************** Export title ***************************
row=2
col=1
Excel.Columns.Columns(1).Columnwidth = 5
Excel.Columns.Columns(2).Columnwidth = 15
Excel.Cells(row,col+1).Value = "CATProduct:"
Excel.Cells(row,col+1).Font.Bold = true
Excel.Cells(row,col+1).HorizontalAlignment = 3
Excel.Cells(row,col+2).Value = CATIA.ActiveDocument.Name
' **************************** Export column titles ***************
row=4
Excel.Cells(row,col+1).Value = "Instance Name"
Excel.Cells(row,col+1).Font.Bold = true
Excel.Columns.Columns(2).Columnwidth = 20
Excel.Cells(row,col+1).borders.LineStyle = 1
Excel.Cells(row,col+1).HorizontalAlignment = 3
Excel.Cells(row+2,col+1).Value = oInProduct.ReferenceProduct.PartNumber
Excel.Cells(row,col+2).Value = "Ref"
Excel.Cells(row,col+2).Font.Bold = true
Excel.Columns.Columns(3).Columnwidth = 15
Excel.Cells(row,col+2).borders.LineStyle = 1
Excel.Cells(row,col+2).HorizontalAlignment = 3
Excel.Cells(row+2,col+2).Value = oInProduct.ReferenceProduct.Nomenclature
Excel.Cells(row,col+3).Value = "Quantity"
Excel.Cells(row,col+3).Font.Bold = true
Excel.Columns.Columns(4).Columnwidth = 15
Excel.Cells(row,col+3).borders.LineStyle = 1
Excel.Cells(row,col+3).HorizontalAlignment = 3
Excel.Cells(row+2,col+3).Value = 1 'insert item quantity corresponding to PartNumber
Excel.Cells(row,col+4).Value = "SinexRef"
Excel.Cells(row,col+4).Font.Bold = true
Excel.Columns.Columns(5).Columnwidth = 15
Excel.Cells(row,col+4).borders.LineStyle = 1
Excel.Cells(row,col+4).HorizontalAlignment = 3
Excel.Cells(row+2,col+4).Value = 1 'insert Sinex Ref corresponding to PartNumber
t = t + 1
Next
End If
Dim k As Integer
For k = 1 To oInstances.Count
Dim oInst As Product
Set oInst = oInstances.Item(k)
Call WalkDownTree(oInst)
Next
End Sub
Assuming by
in the same cell cycles through all of the parts and children in the spec tree
you mean that it is writing/overwriting data from CATIA in the same cell, that is because you aren't incrementing anything regarding Excel rows/columns.
I personally would create headers for things like CATProduct, Instance Name, etc. then put pure data below instead of repeating these identical headers every single time, but your format will work as well, it might just be more difficult to summarize data in Excel.
Anyway, to maintain your existing format, you need to increment your Row at the end of your loop, around where t is incremented.
In the existing loop, it appears that rows 2-6 are used (5 rows total) for the first oInProduct. There is a row = 2 at the beginning of the loop which needs to be put just before the loop, this means it will start from the second row. There is also a row = 4 inside the loop which needs to be changed, we can use row = row + 2 to get the same effect. Then, at the end of the loop, we increment again to reach that total of 5, so use row = row + 3.
row = 2
for i = 1 to oInProduct.Count
'**************************** Export title ***************************
col=1
Excel.Columns.Columns(1).Columnwidth = 5
...
row = row + 2 'previously row = 4
...
Excel.Cells(row,col + 4).HorizontalAlignment = 3
Excel.Cells(row + 2,col + 4).Value = 1 'insert Sinex Ref corresponding to PartNumber
t = t + 1
row = row + 3
Next
Try
-->Analyze-->Bill of Material-->Define Format (for optional options)-->>Save as-->File format as .xls
Or:
-->File--> Save As --> Filetype:txt...Sure it's txt but maybe you can convert to .xls
(expecially if you have missing licenses)
I have used AssemblyConverter object which is available in Catia libraries to extract BOM.I found this when I recorded macro using the steps mentioned in above comment.
Try -->Analyze-->Bill of Material-->Define Format (for optional options)-->>Save as-->File format as .xls
I think this is the simplest and fast. Also, we can change format and location of file too.
Recorded Macro:
Sub CATMain()
Dim productDocument1 As ProductDocument
Set productDocument1 = CATIA.ActiveDocument
Dim product1 As Product
Set product1 = productDocument1.Product
Dim assemblyConvertor1 As AssemblyConvertor
Set assemblyConvertor1 = product1.GetItem("BillOfMaterial")
Dim arrayOfVariantOfBSTR1(4)
arrayOfVariantOfBSTR1(0) = "Quantity"
arrayOfVariantOfBSTR1(1) = "Part Number"
arrayOfVariantOfBSTR1(2) = "Type"
arrayOfVariantOfBSTR1(3) = "Nomenclature"
arrayOfVariantOfBSTR1(4) = "Revision"
Set assemblyConvertor1Variant = assemblyConvertor1
assemblyConvertor1Variant.SetCurrentFormat arrayOfVariantOfBSTR1
Dim arrayOfVariantOfBSTR2(1)
arrayOfVariantOfBSTR2(0) = "Quantity"
arrayOfVariantOfBSTR2(1) = "Part Number"
Set assemblyConvertor1Variant = assemblyConvertor1
assemblyConvertor1Variant.SetSecondaryFormat arrayOfVariantOfBSTR2
assemblyConvertor1.[Print] "XLS", "C:\Users\Desktop\BOM.xls", product1
End Sub
I have a four dropdownlists that are used to filter/order a gridview.
If any of the first 3 dropdowns have a selected value other than 0 the the WhereFlag is set to True. The fourth dropdown is used to dictate which column the grid is ordered by.
My code for databinding the gridview uses System.Linq.Dynamic and is shown below...
Dim dc As New DiaryDataContext
If WhereFlag = False Then
'This section works...
Dim AList = dc.D_AreaSubAreas _
.OrderBy(ddl_SortBy.SelectedValue)
Dim dl As List(Of D_AreaSubArea)
dl = AList.ToList
dl.Insert(0, New D_AreaSubArea With {.Ref = 0,
.Area = "",
.SubArea = "",
.Allocation = "Allocation...",
.Redundant = False})
gv_AreaSubArea.DataSource = dl
gv_AreaSubArea.DataBind()
'Gridview successfully binds
'If ddl_SortBy value is changed... Gridview binds OK.
Else
'This section gives error...
Dim WhereBuild As New StringBuilder
If ddl_AreaFilter.SelectedIndex <> 0 Then
WhereBuild.Append("Area = '" & ddl_AreaFilter.SelectedValue & "'")
AndFlag = True
End If
If ddl_SubAreaFilter.SelectedIndex <> 0 Then
If AndFlag = True Then
WhereBuild.Append(" AND ")
End If
WhereBuild.Append("SubArea = '" & ddl_SubAreaFilter.SelectedValue & "'")
AndFlag = True
End If
If ddl_AllocFilter.SelectedIndex <> 0 Then
If AndFlag = True Then
WhereBuild.Append(" AND ")
End If
WhereBuild.Append("Allocation = '" & ddl_AllocFilter.SelectedValue & "'")
End If
'ERROR HERE
Dim AList = dc.D_AreaSubAreas _
.Where(WhereBuild.ToString) _
.OrderBy(ddl_SortBy.SelectedValue)
'END ERROR
Dim dl As List(Of D_AreaSubArea)
dl = AList.ToList
dl.Insert(0, New D_AreaSubArea With {.Ref = 0,
.Area = "",
.SubArea = "",
.Allocation = "Allocation...",
.Redundant = False})
gv_AreaSubArea.DataSource = dl
gv_AreaSubArea.DataBind()
End If
The error I get is with the dynamic where clause. The error I get is
ParseException is unhandled by user code. Character Literal must contain exactly one character
It points to the query AList in the Else fork. The only difference between it and the query in the If fork is the addition of the Where clause... but I have been unable to deduce what is wrong with my code. AHA.
The error points to the place where the LINQ query is evaluated and, as the message says, the problem is that a character is expected but several characters were provided.
Check whenever ddl_AreaFilter.SelectedValue, ddl_SubAreaFilter.SelectedValue or ddl_AllocFilter.SelectedValue actually contain a character or a string. If they contain more than one character, you should replace ' with \" when building the where condition, for instance:
WhereBuild.Append("Area = """ & ddl_AreaFilter.SelectedValue & """")
EDIT
You must make sure that the type of the value contained in each SelectedValue string match the corresponding database type. For instance, if the database column is a numeric type, the string content will be casted to a numeric type.
When you specify the value in the comparison using quotes, you are indicating that the type on the right side of the comparison is either character or string (depending on whenever you use single or double quotes, respectively).
So, what are the Area, SubArea and Allocation types in the database?
Single character: the value in your query should be around single quotes: Area = 'value'
Strings (for instance, varchar):you must use double quotes: Area = "value"
Other: then you should use no quotes: Area = value