Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 9 years ago.
Improve this question
I would like to add a counter to a power point presentation. Someone mentioned to me that this might be doable in VBA. Do you know if this could be done in VBA and how?
Basically here is what I would like to do:
display a counter representing for example the number of cars rented since the beginning of my presentation. So for example, at the start the counter is at 0 and every minute is incremented of 2000 (this is just an example). We can see the counter on every slide, so at the end of my talk people can see (and I'll tell them) that since the beginning of the talk X(large number) cars have been rented.
I tried to find something on the internet but without success... I hope someone will be able to help me?
I give you some ideas. Possibly they will be helpful even I do not provide any code.
Generally you need to have something like 'timer' in your presentation which would start with your presentation and count the time used. Unfortunately there is nothing like this in PowerPoint. You could possibly use some external solution like C# COM add-in but it's rather very complicated.
You could use PP application events but value of the car will not change every minute but every new slide you enter or any other event fires (like moving reverse, etc). It's a bit complicated but within our (StackOverflow users) knowledge.
You could possible search or ask under that link where I used to find lot's of interesting ideas.
I promised to provide solution therefore I'd like to do it even the question is closed. Therefore I do it by re-edition of that answer which I hope is allowed.
We have to be sure that there is a 'text box' where 'count value' would be placed on each slide. Add the following code into Module1 and run it.
Sub Add_CarValue_Text()
Dim SLD As Slide, SHP As Shape, shCarValue As Shape
Dim boCarValue As Boolean
For Each SLD In ActivePresentation.Slides
For Each SHP In SLD.Shapes
If SHP.Name = "CarValue" Then
boCarValue = True
Exit For
End If
Next
If Not boCarValue Then
Set shCarValue = SLD.Shapes.AddTextbox(msoTextOrientationHorizontal, 0, 0, 150, 50)
With shCarValue
.Name = "CarValue"
.TextFrame.TextRange.Text = "Cars counter: "
End With
End If
boCarValue = False
Next
End Sub
Add new Class Module and place below code there. Change if necessary.
Public WithEvents PPApp As Application
Private TimerStart As Long
Private Const increasePerMinute = 1000
Private Sub PPApp_SlideShowBegin(ByVal Wn As SlideShowWindow)
TimerStart = Int(Timer)
End Sub
Private Sub PPApp_SlideShowNextSlide(ByVal Wn As SlideShowWindow)
If Not Wn.View.Slide.Shapes("CarValue") Is Nothing Then
Dim Lap As Integer
Lap = (Int(Timer) - TimerStart) / 10 'change for 60 to change from 10sec to 1 min
Wn.View.Slide.Shapes("CarValue").TextFrame.TextRange = "Cars volume: " & Lap * increasePerMinute
End If
End Sub
Add the following code to Module2 and run the procedure.
Public tmpPPApp As New AppClass
Sub StartUp()
Set tmpPPApp.PPApp = PowerPoint.Application
End Sub
Start your presentation.
Important! If you change anything in code please run step 3 again. Moreover, just in case, you need to run procedure 3 always before you lunch the presentation.
Related
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
I Believe this question is very common but I am getting a very unique situation.
I have a code that I am using for delay delivery.
But the problem is I am unable to run the macro.
Public Sub Applicaion_Reminder(ByVal Item As Object)
Dim objPeriodicalMail As MailItem
If Item.Class = olTask Then
If InStr(LCase(Item.Subject), "send an email periodically") Then
Set objPeriodicalMail = Outlook.Application.CreateItem(olMailItem)
'Change the following email information as per your actual needs
With objPeriodicalMail
.Subject = "Email to Gmail"
.To = "bfarhan8#gmail.com"
.HTMLBody = "<HTML><BODY>It's a Test</HTML></BODY>"
.Importance = olImportanceHigh
.ReadReceiptRequested = True
.Send
End With
End If
End If
End Sub
When I hit on the run it asks me for Macro Name when I define a name it creates a new Sub.
If I remove the parameters of the
Application_Reminder()
to match the name with a macro name It gives an error on line number 3.
My question is how to run this Macro Properly. I searched the web but didn't find any useful help.
What you have missed is that macros can either be subroutines or functions and for each there are two major types.
A subroutine does something. Your Application_Reminder is a subroutine because it does something: send a reminder. A function can do something, but its real purpose is to return a value.
Some subroutines and functions need parameters, but some do not.
If I write a function Sqrt, the immediate question is: square root of what? I want to be able to write:
Answer = Sqrt(5)
That is, today I want the square root of 5. Tomorrow, I might want the square root of 7.
I would write:
Function Sqrt(ByVal Number as Double) as Double
‘ Code to calculate square root of Number
Sqrt = ResultOfCalculation
End Function
Almost all functions have parameters, but it is not essential. I could have a function, GetCurrentTemperature that reads a thermometer and returns a temperature. It would not need a parameter.
You have written a subroutine that has a parameter: Applicaion_Reminder(ByVal Item As Object). When you try to run Applicaion_Reminder, the interpreter wants to know what Item. I do not think the interpreter’s response is very sensible. It should have just told you, “You cannot run a subroutine with a parameter.”
You need a subroutine without a parameter that decides which Item is to be processed. With some computer languages, that subroutine must have the name Main. With VBA it can have any name.
That is, you need a subroutine like this:
Sub PickAnItemThatNeedsAReminder()
Dim Item as Object
‘ Code to set Item to the required MailItem
Call Applicaion_Reminder(Item)
End Sub
There are four distinct methods of selecting a MailItem. I imagine you scrolling down your Sent Items folder looking for emails to which you have not received a reply. When you find such an email, you run PickAnItemThatNeedsAReminderwhich sends a reminder.
Sub PickAnItemThatNeedsAReminder ()
Dim Exp As Explorer
Dim Item As Object
Set Exp = Outlook.Application.ActiveExplorer
If Exp.Selection.Count = 0 Then
Call MsgBox("Please select one or more emails then try again", vbOKOnly)
Exit Sub
Else
For Each Item In Exp.Selection
Call Applicaion_Reminder(Item)
Next
End If
End Sub
Exp.Selection is a list of all the currently selected emails. You can select as many emails as you want and them run PickAnItemThatNeedsAReminder. It will call Applicaion_Reminder for every selected email.
Additional Background
My belief is you have found a routine that runs off an event and have tried to adapt it to your requirements. Events are an incredibly useful feature of Outlook. However, if you do not yet understand that you cannot run a macro without a parameter, you are not yet ready for events. We say: walk before you run.
BraX and Super Symmetry would be correct in telling you to use ThisOutlookSession if you are going to use events. I have suggested you use Explorer (which is technically an event) but which is much easier for a beginner to understand than an application level event which is what you seemed to have found. With my approach, all your code can be in an ordinary module.
Application.Reminder event Occurs immediately before a reminder is displayed
set up Task Item with reminder then call your vba function - Applicaion_Reminder
See example on this answer
https://stackoverflow.com/a/40144594/4539709
if you want to call it with selected email then see Tony's answer
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 8 years ago.
Improve this question
Hi i really need some help with this, I need to make a multiple choice question program that reads the questions and answers from 2 different text files (notepad files)
but when I try I cant seem to get it working. i have tried loops but that didn't work then I tried arrays but that didn't meet the requirements of reading form a text file
So I come to you all I need help is with reading a text file line by tine and then updating it when a new question needs to be given
I cannot 1 read the line by line (questions.txt) and i need to have match the question which are in answers.txt then i need to update it when next question is clicked
VB.Net
Program i need to create must do the following
Questions and answers should be loaded from a file called questions.txt and answers.txt respectively
-Questions should also appear in random order, every time program is executed
-update form for next question
-keep track on how many questions are correct
Any resources or tutorials on any of the above would be muchly appreciated
Total edits: 198305769 lol. Cleaned up the answer, and this should get you nearly complete. Cheers.
Declare a global variable (integer); that's where you'll assign the amount of questions the user has answered:
Public Class Form1
Dim keepScore As Integer = 0
Not the neatest, but it appends each line from a selected text file into an array and then you can iterate through it.
Dim ofd As New OpenFileDialog
ofd.ShowDialog()
Dim xstr = ofd.FileName
Dim questions() As String = IO.File.ReadAllLines(ofd.FileName)
Dim answers() As String = IO.File.ReadAllLines(ofd.FileName)
Dim sw As New StringBuilder
Dim i As Integer = 0
Do Until i = questions.Count()
sw.AppendLine(Trim(questions(i)))
MsgBox(questions(i)) 'Only added this so you can see the lines
i = i + 1
Loop
Do Until i = answers.Count()
sw.AppendLine(Trim(answers(i)))
MsgBox(answers(i)) 'Only added this so you can see the lines
i = i + 1
Loop
Add onto the end of this function an if statement:
If CorrectAnswer.Checked = True 'Assuming you are using a RadioButton Group, or CheckBox
keepScore = keepScore + 1
End If
Here is a quick number randomiser, assuming you have 20 questions (change the 20 accordingly to whatever amount of questions you have):
Randomize()
Dim i As Integer = CInt(Int(20 * Rnd() + 1))
MsgBox(i)
Best of luck.
I want to save an excel at every 2 seconds. Data is updated in this excel through DDE and want to read this data every 2 seconds. Unfortunately this data is not saved on hard disk.
I am aware of macro which can be used to save file after specified point of time but do not want to use macro.
Since data is updated frequently in this sheet through DDE (at every 100 MS) so sheet change event triggers too often.
Below is the code which i am trying but not getting success.
Dim ctme, ptme As Integer
Private Sub Workbook_Open()
ctme = Second(Now)
ptme = ctme - 2
End Sub
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
ctme = Second(Now)
If (ctme - ptme) = 2 Then
Me.Save
ptme = ctme
End If
End Sub
Please help
Nidhi, people here are trying to help you and you need to understand that no one has the access to your brain to understand what you actually meant to ask. So it is quite natural to ask questions to understand the issue clearly before suggesting any answer. The people here, get equally frustrated when they are unable to understand a simple question, the time they spend could have been easily saved, had the person spent a little extra time in explaining the things better. So giving credit to those who are trying to help you, will not harm at all.
Ok, coming back to your question. I may be wrong, but I think that SheetChange event is not fired on DDE update. Please correct me if I am wrong.
The next option can be Application.OnTime functionality.
Write the following code in Workbook Open Method:
Private Sub Workbook_Open()
Dim currentTime As Date
currentTime = DateAdd("s", 2, Now)
Application.OnTime currentTime, "SaveFile"
End Sub
Then Add a new Module and add the following Function there in new Module:
Public Sub SaveFile()
ThisWorkbook.Save
Dim currentTime As Date
currentTime = DateAdd("s", 2, Now)
Application.OnTime currentTime, "SaveFile"
End Sub
The above code will create a timer which would run every two seconds to save your file. There are pros and cons for this approach, but it's Excel's best possible Timer functionality. Let me know if you have any questions.
Thanks,
Vikas
(this is totally away from the OP tags but just thought I'd put forward a possible alternative)
Create a small .NET console application.
User one of the Timer objects available to create this timed loop you require.
Then using a reference to Excel Interop library on each sweep of the loop it looks like you might need to open this workbook, save it, and then close it again .....depending on the calculations within the book and the size of the Excel file is it physically possible on your machine to open/calculate/save within 2 seconds?
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I am making a hangman game for my son, in VB.net. I have made buttons for each letter, and i have also made a list of words. The problem I am encountering is when I am trying to print the guessed letters to the labels. I don´t know how to this. Can anyone help me please?
I will try to help you although you haven't show your code.
A simple approach is:
Private sWord As String 'Your word here
Dim arrayLetters As Array
arrayLetters = sWord.ToCharArray
For i = 0 To arrayLetters.Length - 1
Dim lbl As New Label
lbl.Text = "_"
lbl.Tag = arrayLetters(i)
lbl.AutoSize = True
Me.FlowLayoutPanel1.Controls.Add(lbl) ' Assuming that you have added a FlowLayoutPanel in your form to handle your labels (AutoSizeMode=GrowAndShrink)
Next
Now you need a sub to check the if the user has pressed the right letter:
Private Sub CheckLetter(ByVal letter As Char)
For Each lbl As Label In FlowLayoutPanel1.Controls
If lbl.Tag = letter Then
lbl.Text = letter
Else
'Whatever you like if the user make a mistake
End If
Next
End Sub
Now in the event that handles the buttons click
CheckLetter("Here you put the corresponding letter")
Of course you can have one event to handle all the letters (or even use keyboard for input),add capital letters etc.
Show us your efforts
I want to make a special list of figures with use of VBA and here I am using the function
myFigures = ActiveDocument.GetCrossReferenceItems(Referencetype:="Figure")
In my word document there are 20 figures, but myFigures only contains the first 10 figures (see my code below.).
I search the internet and found that others had the same problem, but I have not found any solutions.
My word is 2003 version
Please help me ....
Sub List()
Dim i As Long
Dim LowerValFig, UpperValFig As Integer
Dim myTables, myFigures as Variant
If ActiveDocument.Bookmarks.Count >= 1 Then
myFigures = ActiveDocument.GetCrossReferenceItems(Referencetype:="Figure")
' Test size...
LowerValFig = LBound(myFigures) 'Get the lower boundry number.
UpperValFig = UBound(myFigures) 'Get the upper boundry number
' Do something ....
For i = LBound(myFigures) To UBound(myFigures) ‘ should be 1…20, but is onlu 1…10
'Do something ....
Next i
End If
MsgBox ("Done ....")
End Sub*
Definitely something flaky with that. If I run the following code on a document that contains 32 Figure captions, the message boxes both display 32. However, if I uncomment the For Next loop, they only display 12 and the iteration ceases after the 12th item.
Dim i As Long
Dim myFigures As Variant
myFigures = ActiveDocument.GetCrossReferenceItems("Figure")
MsgBox myFigures(UBound(myFigures))
MsgBox UBound(myFigures)
'For i = 1 To UBound(myFigures)
' MsgBox myFigures(i)
'Next i
I had the same problem with my custom cross-refference dialog and solved it by invoking the dialog after each command ActiveDocument.GetCrossReferenceItems(YourCaptionName).
So you type:
varRefItemsFigure1 = ActiveDocument.GetCrossReferenceItems(g_strCaptionLabelFigure1)
For k = 1 To UBound(varRefItemsFigure1)
frmBwtRefDialog.ListBoxFigures.AddItem varRefItemsFigure1(k)
Next
and then:
frmBwtRefDialog.Show vbModeless
Thus the dialog invoked several times instead of one, but it works fast and don't do any trouble. I used this for one year and didn't see any errors.
Enjoy!
Frankly I feel bad about calling this an "answer", but here's what I did in the same situation. It would appear that entering the debugger and stepping through the GetCrossReferenceItems always returns the correct value. Inspired by this I tried various ways of giving control back to Word (DoEvents; running next segment using Application.OnTime) but to no avail. Eventually the only thing I found that worked was to invoke the debugger between assignments, so I have:
availRefs =
ActiveDocument.GetCrossReferenceItems(wdRefTypeNumberedItem):Stop
availTables =
ActiveDocument.GetCrossReferenceItems(wdCaptionTable):Stop
availFigures = ActiveDocument.GetCrossReferenceItems(wdCaptionFigure)
It's not pretty but, as I'm the only person who'll be running this, it kind of works for my purposes.