I am using IPP.Net to attempt to insert a single CreditMemo into Quickbooks Online. I have been successful inserting an invoice with similar code. My code for inserting the CreditMemo is as follows:
Try
Dim qboCreditMemo As New Intuit.Ipp.Data.Qbo.CreditMemo
Dim qboCreditMemoHdr As New Intuit.Ipp.Data.Qbo.CreditMemoHeader
Dim qboCreditMemoLine As Intuit.Ipp.Data.Qbo.CreditMemoLine
Dim CreditMemoLines As New List(Of Intuit.Ipp.Data.Qbo.CreditMemoLine)
Dim CreditMemoItemAttributes As Qbo.ItemChoiceType2()
Dim CreditMemoItemValues As Object()
For Each row In tblTrans.Rows
If bFirstRow Then
'Set CreditMemo header
qboCreditMemoHdr.DocNumber = "SMA" & CStr(row("batch_id"))
qboCreditMemoHdr.TxnDate = Format(row("acct_date"), "yyyy-MM-dd")
qboCreditMemoHdr.Msg = row("batch_descr")
qboCreditMemoHdr.CustomerId = New Intuit.Ipp.Data.Qbo.IdType
qboCreditMemoHdr.CustomerId.Value = row("iface_owner_id")
qboCreditMemo.Header = qboCreditMemoHdr
bFirstRow = False 'only do this once
End If
'Lines
qboCreditMemoLine = New Qbo.CreditMemoLine
qboCreditMemoLine.Desc = row("descr")
qboCreditMemoLine.Amount = row("amount_owner")
qboCreditMemoLine.AmountSpecified = True
CreditMemoItemAttributes = {Qbo.ItemsChoiceType2.ItemId, Qbo.ItemsChoiceType2.UnitPrice, Qbo.ItemsChoiceType2.Qty}
CreditMemoItemValues = {New Qbo.IdType With {.idDomain = Qbo.idDomainEnum.QBO, .Value = row("iface_item_id")}, row("unitPrice"), row("quantity")}
qboCreditMemoLine.ItemsElementName = CreditMemoItemAttributes
qboCreditMemoLine.Items = CreditMemoItemValues
qboCreditMemoLine.ClassId = New Intuit.Ipp.Data.Qbo.IdType
qboCreditMemoLine.ClassId.Value = row("iface_class_id")
CreditMemoLines.Add(qboCreditMemoLine) 'Add line to list of lines
Next row
qboCreditMemo.Line = CreditMemoLines.ToArray 'Add CreditMemo lines to CreditMemo lines property
resultCreditMemo = commonService.Add(qboCreditMemo) 'Add CreditMemo to request
Return "OK"
'Catch exID As Intuit.Ipp.Exception.IdsException
'Return exID.Message
Catch ex As Exception
Return ex.Message
End Try
I got an error with message 'Internal Server Error'. It seems to be an IdsException. As indicated in my other article, I was able to get detailed information for a BatchRequest through the Fault and Error objects. However, I do not understand how to get the details on this error for a single invoice using Dataservices.
I think I may need better error handling, assuming there is more information available for this error. And, I need help figuring out why the same properties that I set for an invoice would not work for a CreditMemo. Unfortunately the documentation in the Intuit website where the required properties are listed does not include a CreditMemo (though it includes an Invoice).
CreditMemo is not supported in QBO:
https://ipp.developer.intuit.com/0010_Intuit_Partner_Platform/0050_Data_Services/0400_QuickBooks_Online/0500_Supported_Entities_and_Operations
I had almost the same issue, and the problem was that the qty and amount should not be negative. I changed it on my creditmemoLine and it worked
Related
I try to coding is sending Rich text field via email , but I find an error that's I think this method for sending email, by following code
Sub Click(Source As Button)
Dim s As New NotesSession
Dim w As New NotesUIWorkspace
Dim db As NotesDatabase
Dim doc As NotesDocument
Dim uidoc As NotesUIDocument
Set uidoc = w.CurrentDocument
Set s = New NotesSession
Set w = New NotesUIWorkspace
Set db = s.CurrentDatabase
Set doc = New NotesDocument (db)
doc.sendTo =s.UserName
doc.Subject = "Employee Information"
Dim rt As NotesRichTextItem
Set rt = New NotesRichTextItem ( doc, "Body" )
'Dim file As Variant 'if I use this code for declare for get value; Error : Type Mismatch
'Set file = doc.GetFirstItem("Body")
Dim rtitem As NotesRichTextItem 'if I use this code for declare for get value ; Error : Missing text object
Set rtitem = doc.GetFirstItem( "Body" )
Call rt.AppendRTItem(rtitem)
doc.Send(False)
End Sub
One thing I notice is that you don't set the form on the mail document you are creating.
You have some code you don't need, since you don't use uidoc anywhere, no need for that or declaring a NotesUIWorkspace object.
I also recommend that you use better variable names, and not to use extended notation when you set field values in a NotesDocument object.
I suggest that you take a look at the articles here:
http://blog.texasswede.com/how-to-write-better-code-in-notesdomino/
Below is the code that I cleaned up:
Option Public
Option Declare
Sub Click(Source As Button)
Dim session As New NotesSession
Dim ws As New NotesUIWorkspace
Dim db As NotesDatabase
Dim mailDoc As NotesDocument
Dim mailBody As NotesRichTextItem
Set db = session.CurrentDatabase
Set mailDoc = New NotesDocument(db)
Call mailDoc.ReplaceItemValue("Form","Memo")
Call mailDoc.ReplaceItemValue("SendTo",session.UserName)
Call mailDoc.ReplaceItemValue("Subject","Employee Information")
Set mailBody = New NotesRichTextItem(mailDoc,"Body" )
'Dim file As Variant 'if I use this code for declare for get value; Error : Type Mismatch
'Set file = doc.GetFirstItem("Body")
Dim rtitem As NotesRichTextItem 'if I use this code for declare for get value ; Error : Missing text object
Set rtitem = doc.GetFirstItem("Body")
Call mailBody.AppendRTItem(rtitem)
Call mailDoc.Send(False)
End Sub
The big question here is where you are getting the rich text field you want to send from? In your original code you are trying to read it from the newly created document (the one I call mailDoc). But that does not make any sense.
Your problem is simply that you are not reading the rich text from anywhere.
If your goal is to send an email, you can use my mail notification class:
http://blog.texasswede.com/updated-mailnotification-class-now-with-html-email-support-and-web-links/
Then your code would look something like this:
Dim session As New NotesSession
Dim mail As NotesMail
' *** Create a mail
Set mail = New NotesMail()
' Set receipient and subject
mail.MailTo = session.CommonUsername
mail.Subject = "Employee Information"
mail.Principal = "noreply#example.com"
' Create body content from rtitem.
' Yes, I should have added a method in the
' class to append RichtText to the mail body...
mail.body.AppendRTItem(rtitem)
Call mail.Send()
The only thing you have to do is to get the rtitem from somewhere. Since your original code declared a NotesUIWorkSpace object and a NotesUIDocument object, I am guessing you want to read it from the currently open document. Then you just add the following to the beginning of the code:
Dim ws As New NotesUIWorkspace
Dim thisdoc As NotesDocument
Dim rtitem as NotesRichTextItem
Set thisdoc = ws.CurrentDocument.Document
Set rtitem = thisdoc.GetFirstItem("Body")
Do you also see how much easier it is to read when you use descriptive variable names?
Hi you did not saved the document. Please be aware the Richtext is not available if the document is not saved.
I have a question. For example there is one view and 10 documents are in that view. Out of all those documents, 8 of them I should be the recipient of the email (based on the field value which is my email address).
Now, what I want to happen is that I will be receiving only one email for all those 8 documents, and in that email I there will be 8 doclinks.
Is that possible?
'Cause currently I am getting 8 emails and for each email, there is one doclink. Thanks in advance for those who can help me.
Dim s As NotesSession
Dim db As NotesDatabase
Dim doc As NotesDocument
Dim rtitem As NotesRichTextItem
Dim i As Integer
Dim view As NotesView
Set s = New NotesSession
Set db = s.CurrentDatabase
Set view = db.GetView("View")
Set doc = New NotesDocument(db)
Dim addresses As NotesName
i=0
Set doc = view.GetFirstDocument
While Not(doc Is Nothing)
Set addresses = New NotesName(doc.Manager(0))
If addresses.abbreviated = "" Then
i = i + 1
Else
doc.SendTo = addresses.abbreviated
doc.Form = "Memo"
Set rtitem = New NotesRichTextItem(doc, "Body")
Call rtitem.AppendText("Balance")
Call rtitem.appenddoclink(doc, "Link")
doc.Send (True)
i = i + 1
End If
Set doc = view.GetNextDocument(doc)
Wend
As Thorsten said, it can be done. There are a couple of ways to handle this, depending on how flexible and future proof you want it, and how "clean" of a solution you want.
Let's say you have 10 documents, 8 with your email and 2 with a different user's email. I assume you want to send one mail to you with 8 doc links and one to the other person with 2 doc links.
The way I would do it is to create a class. That class would contain a list of NotesDocuments (and a method to add documents to the list):
Class DocData
Public docs List As NotesDocument
Public Sub New()
End Sub
Public Sub Add(doc as NotesDocument)
Set docs(doc.UniversalID) = doc
End Sub
End Class
In your main code, you have a list of DocData objects, one per mail recipient:
Dim docs List As DocData
You now loop through the view or the document collection you have. You check the email address for each document and if there isn't a list item for that address, you create it and add the document to it. If it already exists, just add the document:
email = doc.GetItemValue("EmailAddress")(0)
If !IsElement(docs(email)) Then
Set docs(email) = New DocData()
End If
Call docs(email).Add(doc)
When all documents have been processed, you should have a list with one item per mail recipient, and you can loop through the list, build one email per item and populate it with doc links for all the documents in the list in the object.
For performance reasons, if you plan to have this working on larger views with more documents, I woudl suggest that you put the email address in one of the columns, and then use view entries to loop though the documents, and ColumnValues() to read the email address.
I wrote about it here: http://blog.texasswede.com/re-using-lotusscript-lists-to-increase-performance/
Your code can be slightly modified to only send one mail:
Dim s As NotesSession
Dim db As NotesDatabase
Dim doc As NotesDocument
Dim rtitem As NotesRichTextItem
Dim i As Integer
Dim view As NotesView
Set s = New NotesSession
Set db = s.CurrentDatabase
Set view = db.GetView("View")
Set doc = New NotesDocument(db)
Dim addresses As NotesName
i=0
'- prepare mail
doc.Form = "Memo"
Set rtitem = New NotesRichTextItem(doc, "Body")
Call rtitem.AppendText("Balance")
Set doc = view.GetFirstDocument
While Not(doc Is Nothing)
Set addresses = New NotesName(doc.Manager(0))
If addresses.abbreviated = "" Then
i = i + 1
Else
'- Set recipient
If not doc.HasItem( "SendTo" ) then
doc.SendTo = addresses.abbreviated
End If
'- Append descriptive text, link and new line
Call rtitem.appendtext(doc.Subject(0) & " " )
Call rtitem.appenddoclink(doc, "Link")
Call rtitem.addnewline(1)
i = i + 1
End If
Set doc = view.GetNextDocument(doc)
Wend
'- send mail
Call doc.Send (True)
with that code the mail is first prepared, then a doclink is added for every document, and in the end the mail is sent.
So I was advised that I could create some copy replace functionality to this form.
Here is my coding attempt in VB:
First I connect to DB using DAO. Then I use a SELECT statement that has been verified to pull the last record inserted into the DB. Then I try to refill the controls with the values from the query but I am getting reference errors.
Private Sub AutoFill_Click()
Dim db As DAO.Database, rs As DAO.Recordset
Dim strSQL As String
Set db = CurrentDb()
strSQL = "SELECT DISTINCTROW TOP 1 CPOrders.Cust, Customer.NAME, CPOrders.CP_Ref, CPOrders.Slsman, CPOrders.Date_opn, CPOrders.CPSmall, CPOrders.InvIssu, CPOrders.InvNo, CPOrders.InvDate, CPOrders.DueDate, CPOrders.ETADate, CPOrders.Closed, CPOrders.BuyerRef, CPOrders.ToCity, CPOrders.ToState, CPOrders.ToCtry, CPOrders.ToPort, CPOrders.Supplier, CPOrders.Origin, CPOrders.Product, CPOrders.GradeType, CPOrders.NoUnits, CPOrders.Pkg, CPOrders.Qty, CPOrders.TotSale, CPOrders.TotCost, CPOrders.GrMargin, CPOrders.[Sale$/Unit], CPOrders.[Cost$/Unit], CPOrders.OceanCost, CPOrders.OceanNotes, CPOrders.BLadingDate, CPOrders.USAPort, CPOrders.FOBCost, CPOrders.FASExportVal, CPOrders.InlandFrt, CPOrders.CommodCode, CPOrders.Notes FROM Customer INNER JOIN CPOrders ON Customer.[CUST_#] = CPOrders.Cust ORDER BY CPOrders.CP_Ref desc;"
Set rs = db.OpenRecordset(strSQL, dbOpenDynaset, dbReadOnly)
rs.MoveFirst
CP_Ref.ControlSource = rs!CP_Ref
Slsman.ControlSource = rs!Slsman
CPSmall.ControlSource = rs!CPSmall
InvIssu.ControlSource = rs!InvIssu
InvDate.ControlSource = rs!InvDate
DueDate.ControlSource = rs!DueDate
Closed.ControlSource = rs!Closed
rs.Close
db.Close
The control source reference picks up and autocompletes the word.
I would think that as it stands. although i'm not filling all the values with records from my SELECT statement that it would populate but instead i get things like #NAME? where the values should be. I also get a break in my code and it says "Invalid use of null"
Why? I appreciate your guys input and I can provider screenshots if necessary. I think this is involving the reference tie, but I'm not sure. Any help is much appreciated.
You are using the field names from the SELECT statement as if they were variables.
CP_Ref.ControlSource = rs("CP_Ref")
Slsman.ControlSource = rs("Slsman")
CPSmall.ControlSource = rs("CPSmall")
InvIssu.ControlSource = rs("InvIssu")
InvDate.ControlSource = rs("InvDate")
DueDate.ControlSource = rs("DueDate")
Closed.ControlSource = rs("Closed")
When you have that worked out, tackle the "Invalid use of null" problem by first identifying any fields that could potentially be NULL and using something like
SELECT Iif(IsNull([InvDate]), '', [InvDate]) As [InvDate], ...
in the SELECT statement to pass across a minimum of an empty string rather than a NULL value.
I have a table and form setup to control another form in my database.
I'm wanting to make a code that will take the title from my field and add it to my code as a variable to change the visibility options of my other form.
my form is set with all the of the names to all objects on the form I want to control.
LSE_FORM_ADMIN = The table with all the LSE_FORM_ALL names in it.
Table is setup with 3 columns key, names and a checkbox which I put into a form to make a continuous list.
here is my code on the form, but I keep getting and runtime 424: object required error:
Private Sub Form_Current()
Dim VARSET As Object
Dim VAR As String
VARSET = DLookup("TITLE", Table!LSE_FORM_ADMIN, "") 'keep getting error here
VAR = VARSET
If Me!CB = "-1" Then
Form_LSE_FORM_ALL!VAR.Visible = True
Else
Form_LSE_FORM_ALL!VAR.Visible = False
End If
End Sub
can someone help me fix this code so that it will grab the title field data and make it a variable to add to the rest of the code?
It's difficult to see exactly what you are trying to achieve, but your problems stem from using the variant variable type when you should be using an explicit Form or Control type. Using your last example.
RSTT.Visible = True 'getting Run-time error '424': object required
This is because you have declared RSTT as a variant. The line
RSTT = "Form_LSE_FORM_ALL" & "!" & (RST)
results in the variable RSTT containing a string, which does not have a property ".Visible"
Set DB = CurrentDb
Set RS = DB.OpenRecordset("LSE_FORM_ADMIN")
These lines are redundant as you have the values that you need available on the form fields which are already bound to the table LSE_FORM_ADMIN.
As far as I understand, you have a continuous form (ADMIN?) bound to the table LSE_FORM_Admin. As you step through the records on this form, you want code to be fired which takes the value of the TITLE field/control and use it to set a control with the same name, on a separate form, Form_LSE_FORM_ALL, to be (in)visible, dependent on the value of the checkbox control name CB on the ADMIN form?
If you want the ADMIN form to make the changes "live" to the ALL form, you should consider using an event of the CB checkbox control. Using the current event of the form means that the changes you make will not be reflected in the ALL form until you step out of the record you have just edited, then back in, to fire the form's Current event on that record.
Example using AfterUpdate event of CB checkbox
Private Sub CB_AfterUpdate()
Dim strRST As String
Dim frmTarget as Form
Dim ctlRSTT As Control
Set strRST = Me!TITLE
Set frmTarget = Forms("Form_LSE_FORM_ALL")
Set ctlRSTT = frmTarget.Controls(strRST)
ctlRSTT.Visible = Me!CB 'getting Run-time error '424': object required
End Sub
really not sure how to do the syntax when doing a recordset to a table from the form, need some help with that.
here is my code and attempt at the record set:
Private Sub Form_Current()
Dim DB As Database
Dim RS As Recordset
Dim RST As String
Set DB = CurrentDb
Set RS = DB.OpenRecordset("LSE_FORM_ADMIN")
Set RST = RS 'GETTING OBJECT REQUIRED ERROR ON "RST ="
Do Until RS.EOF
RST = Me!TITLE
RS.MoveNext
Loop
If Me!CB = "-1" Then
Form_LSE_FORM_ALL!RS.Visible = True
Else
Form_LSE_FORM_ALL!RS.Visible = False
End If
End Sub
I think I know what you are trying to do, but your descriptions / references are not matching up. Please look at the following comments and clarify:
1. You say "...make a code that will take the title from my field and ..." but your code is taking "Me.Title", "ME" is a reference to the Form - not a field.
2. Your code is in the "Form_Current" event, which means it will fire for every record you process. That will work, but I think you want to do this code only once to be more efficient.
3. You have no provision for processing more than one field. I think you need to loop through all fields in your table, setting visible to true or false.
The following is my suggestion, but I will update once you clarify the issues.
Option Compare Database
Option Explicit
Dim DB As DAO.Database
Dim RS As DAO.Recordset
'Dim RST As Variant
'Dim RSTT As Variant
Public Sub FORM_CURRENT()
Set DB = CurrentDb
Set RS = DB.OpenRecordset("LSE_FORM_ADMIN")
Do While Not RS.EOF ' Loop thru all field names for the form
If RS!HideYN = True Then ' Desire to hide the field?
Me(RS!ctlname).Visible = False ' Yes, hide the field.
Else
Me(RS!ctlname).Visible = True ' No, show the field
End If
RS.MoveNext ' Get next field name
Loop
RS.Close
Set RS = Nothing
Set DB = Nothing
'Set RST = Me!Title
'RSTT = "Form_LSE_FORM_ALL" & "!" & (RST)
'If Me!CB = "-1" Then
' RSTT.Visible = True 'getting Run-time error '424': object required
'Else
' RSTT.Visible = False
'End If
End Sub
Final code, thanks to Cheesenbranston.
Private Sub Form_AfterUpdate()
Dim strRST As String
Dim frmTarget As Form
Dim ctlRSTT As Control
strRST = Me!TITLE
Set frmTarget = Forms("LSE_FORM_ALL")
Set ctlRSTT = frmTarget.Controls(strRST)
If Me!CB = "-1" Then
ctlRSTT.Visible = True
Else
ctlRSTT.Visible = False
End If
End Sub
#Cheesenbranston: Your original code was more like a toggle of on and off so if my object was not visible then my trigger checkbox would make it visible when checked, more of a quality of life for my own needs, none the less worked. Also strRST doesn't need SET since its just a String. Thanks again =D very happy day!
I am trying to write a button handler in VB.NET that will read rows from a gridview and write them to a DB if a checkbox is checked.
I setup this application to use EntityDataSource and added my .edmx file to a DAL folder. I have the button method written but I do not know enough about EF to know how to handle the data the data from the gridview. Here is my btn_click method:
Private Sub btnGetChecks_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnGetChecks.Click
'********************************************
'* gets status of checkbox and writes to db *
'********************************************
Dim row As GridViewRow
Label6.Text = ""
For Each row In DvsGridView.Rows
Dim RowCheckBox As CheckBox = CType(row.FindControl("chkStatus"), CheckBox)
If RowCheckBox.Checked Then
Label6.Text += row.Cells(5).Text & " Checked "
' Need to write checked data to the db
' ******* WHAT GOES HERE? *******
Else
Label6.Text += row.Cells(5).Text & " Unchecked "
End If
Next
End Sub
I am fairly new to EDMX but understand VB.net. Any direction would be greatly appreciated.
Check this sample code and modify this to match your entities and objects
Using db As New DBEntities()
'set values here
Dim x As New TableNameE()
x.col1 = "value1"
x.col2 = "value2"
db.AddToTableNameE(x)
db.SaveChanges()
End Using
Thanks to #rs., I was able to figure out my issues. Referring to the accepted answer, for those wondering what .AddToTableNameE() should be in your proj, it's just going to be .Add(x). It's also somewhat a performance hit using .SaveChanges() for every row, you should create a Dim List(Of TableNameE()) and add the "x" to the list, then use .AddRange() like this:
//creating a data access class is one way to connect to your db by passing in db path
Dim context As New Namespace.YourContext(New DataAccessClass() With {.Path = aBrowsedForSDFFileTextBoxMaybe.Text})
Dim listOfTableObjects As List(Of Namespace.TableObject) = New List(Of Namespace.TableObject)
For n = 1 To SomethingRelatedToRows
Dim tableObject As New Namespace.TableObject() With {
.entityProp1 = TableObject(n).entityProp1,
.entityProp2 = TableObject(n).entityProp2,
.entityProp3 = TableObject(n).entityProp3,
.entityProp4 = TableObject(n).entityProp4,
.entityProp5 = TableObject(n).entityProp5,
.entityProp6 = TableObject(n).entityProp6
}
listOfTableObjects.Add(tableObject)
Next n
//.TableObjects being the DbSet from the ...Context.vb file
context.TableObjects.AddRange(listOfTableObjects)
context.SaveChanges()